Annotation of Gnu-Mach/linux/src/drivers/net/ni65.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * ni6510 (am7990 'lance' chip) driver for Linux-net-3
        !             3:  * BETAcode v0.71 (96/09/29) for 2.0.0 (or later)
        !             4:  * copyrights (c) 1994,1995,1996 by M.Hipp
        !             5:  * 
        !             6:  * This driver can handle the old ni6510 board and the newer ni6510 
        !             7:  * EtherBlaster. (probably it also works with every full NE2100 
        !             8:  * compatible card)
        !             9:  *
        !            10:  * To compile as module, type:
        !            11:  *     gcc -O2 -fomit-frame-pointer -m486 -D__KERNEL__ -DMODULE -c ni65.c
        !            12:  * driver probes: io: 0x360,0x300,0x320,0x340 / dma: 3,5,6,7
        !            13:  *
        !            14:  * This is an extension to the Linux operating system, and is covered by the
        !            15:  * same Gnu Public License that covers the Linux-kernel.
        !            16:  *
        !            17:  * comments/bugs/suggestions can be sent to:
        !            18:  *   Michael Hipp
        !            19:  *   email: [email protected]
        !            20:  *
        !            21:  * sources:
        !            22:  *   some things are from the 'ni6510-packet-driver for dos by Russ Nelson'
        !            23:  *   and from the original drivers by D.Becker
        !            24:  *
        !            25:  * known problems:
        !            26:  *   - on some PCI boards (including my own) the card/board/ISA-bridge has
        !            27:  *     problems with bus master DMA. This results in lotsa overruns.
        !            28:  *     It may help to '#define RCV_PARANOIA_CHECK' or try to #undef
        !            29:  *     the XMT and RCV_VIA_SKB option .. this reduces driver performance.
        !            30:  *     Or just play with your BIOS options to optimize ISA-DMA access.
        !            31:  *     Maybe you also wanna play with the LOW_PERFORAMCE and MID_PERFORMANCE
        !            32:  *     defines -> please report me your experience then
        !            33:  *   - Harald reported for ASUS SP3G mainboards, that you should use
        !            34:  *     the 'optimal settings' from the user's manual on page 3-12!
        !            35:  *
        !            36:  * credits:
        !            37:  *   thanx to Jason Sullivan for sending me a ni6510 card!
        !            38:  *   lot of debug runs with ASUS SP3G Boards (Intel Saturn) by Harald Koenig
        !            39:  *
        !            40:  * simple performance test: (486DX-33/Ni6510-EB receives from 486DX4-100/Ni6510-EB)
        !            41:  *    average: FTP -> 8384421 bytes received in 8.5 seconds
        !            42:  *           (no RCV_VIA_SKB,no XMT_VIA_SKB,PARANOIA_CHECK,4 XMIT BUFS, 8 RCV_BUFFS)
        !            43:  *    peak: FTP -> 8384421 bytes received in 7.5 seconds 
        !            44:  *           (RCV_VIA_SKB,XMT_VIA_SKB,no PARANOIA_CHECK,1(!) XMIT BUF, 16 RCV BUFFS)
        !            45:  */
        !            46: 
        !            47: /*
        !            48:  * 96.Sept.29: virt_to_bus stuff added for new memory modell
        !            49:  * 96.April.29: Added Harald Koenig's Patches (MH)
        !            50:  * 96.April.13: enhanced error handling .. more tests (MH)
        !            51:  * 96.April.5/6: a lot of performance tests. Got it stable now (hopefully) (MH)
        !            52:  * 96.April.1: (no joke ;) .. added EtherBlaster and Module support (MH)
        !            53:  * 96.Feb.19: fixed a few bugs .. cleanups .. tested for 1.3.66 (MH)
        !            54:  *            hopefully no more 16MB limit
        !            55:  *
        !            56:  * 95.Nov.18: multicast tweaked (AC).
        !            57:  *
        !            58:  * 94.Aug.22: changes in xmit_intr (ack more than one xmitted-packet), ni65_send_packet (p->lock) (MH)
        !            59:  *
        !            60:  * 94.July.16: fixed bugs in recv_skb and skb-alloc stuff  (MH)
        !            61:  */
        !            62: 
        !            63: #include <linux/kernel.h>
        !            64: #include <linux/sched.h>
        !            65: #include <linux/string.h>
        !            66: #include <linux/ptrace.h>
        !            67: #include <linux/errno.h>
        !            68: #include <linux/ioport.h>
        !            69: #include <linux/malloc.h>
        !            70: #include <linux/interrupt.h>
        !            71: #include <linux/delay.h>
        !            72: #include <asm/bitops.h>
        !            73: #include <asm/io.h>
        !            74: #include <asm/dma.h>
        !            75: 
        !            76: #include <linux/netdevice.h>
        !            77: #include <linux/etherdevice.h>
        !            78: #include <linux/skbuff.h>
        !            79: 
        !            80: #include <linux/version.h>
        !            81: #include <linux/module.h>
        !            82: 
        !            83: #include "ni65.h"
        !            84: 
        !            85: /*
        !            86:  * the current setting allows an acceptable performance
        !            87:  * for 'RCV_PARANOIA_CHECK' read the 'known problems' part in 
        !            88:  * the header of this file
        !            89:  * 'invert' the defines for max. performance. This may cause DMA problems
        !            90:  * on some boards (e.g on my ASUS SP3G)
        !            91:  */
        !            92: #undef XMT_VIA_SKB
        !            93: #undef RCV_VIA_SKB
        !            94: #define RCV_PARANOIA_CHECK
        !            95: 
        !            96: #define MID_PERFORMANCE
        !            97: 
        !            98: #if   defined( LOW_PERFORMANCE )
        !            99:  static int isa0=7,isa1=7,csr80=0x0c10;
        !           100: #elif defined( MID_PERFORMANCE )
        !           101:  static int isa0=5,isa1=5,csr80=0x2810;
        !           102: #else  /* high performance */
        !           103:  static int isa0=4,isa1=4,csr80=0x0017;
        !           104: #endif
        !           105: 
        !           106: /*
        !           107:  * a few card/vendor specific defines
        !           108:  */
        !           109: #define NI65_ID0    0x00
        !           110: #define NI65_ID1    0x55
        !           111: #define NI65_EB_ID0 0x52
        !           112: #define NI65_EB_ID1 0x44
        !           113: #define NE2100_ID0  0x57
        !           114: #define NE2100_ID1  0x57
        !           115: 
        !           116: #define PORT p->cmdr_addr
        !           117: 
        !           118: /*
        !           119:  * buffer configuration
        !           120:  */
        !           121: #if 1
        !           122: #define RMDNUM 16
        !           123: #define RMDNUMMASK 0x80000000 
        !           124: #else
        !           125: #define RMDNUM 8
        !           126: #define RMDNUMMASK 0x60000000 /* log2(RMDNUM)<<29 */
        !           127: #endif
        !           128: 
        !           129: #if 0
        !           130: #define TMDNUM 1
        !           131: #define TMDNUMMASK 0x00000000
        !           132: #else
        !           133: #define TMDNUM 4
        !           134: #define TMDNUMMASK 0x40000000 /* log2(TMDNUM)<<29 */
        !           135: #endif
        !           136: 
        !           137: /* slightly oversized */
        !           138: #define R_BUF_SIZE 1544
        !           139: #define T_BUF_SIZE 1544
        !           140: 
        !           141: /*
        !           142:  * lance register defines
        !           143:  */
        !           144: #define L_DATAREG 0x00
        !           145: #define L_ADDRREG 0x02
        !           146: #define L_RESET   0x04
        !           147: #define L_CONFIG  0x05
        !           148: #define L_BUSIF   0x06
        !           149: 
        !           150: /* 
        !           151:  * to access the lance/am7990-regs, you have to write
        !           152:  * reg-number into L_ADDRREG, then you can access it using L_DATAREG
        !           153:  */
        !           154: #define CSR0  0x00
        !           155: #define CSR1  0x01
        !           156: #define CSR2  0x02
        !           157: #define CSR3  0x03
        !           158: 
        !           159: #define INIT_RING_BEFORE_START 0x1
        !           160: #define FULL_RESET_ON_ERROR    0x2
        !           161: 
        !           162: #if 0
        !           163: #define writereg(val,reg) {outw(reg,PORT+L_ADDRREG);inw(PORT+L_ADDRREG); \
        !           164:                            outw(val,PORT+L_DATAREG);inw(PORT+L_DATAREG);}
        !           165: #define readreg(reg) (outw(reg,PORT+L_ADDRREG),inw(PORT+L_ADDRREG),\
        !           166:                        inw(PORT+L_DATAREG))
        !           167: #if 0
        !           168: #define writedatareg(val) {outw(val,PORT+L_DATAREG);inw(PORT+L_DATAREG);}
        !           169: #else
        !           170: #define writedatareg(val) {  writereg(val,CSR0); }
        !           171: #endif
        !           172: #else
        !           173: #define writereg(val,reg) {outw(reg,PORT+L_ADDRREG);outw(val,PORT+L_DATAREG);}
        !           174: #define readreg(reg) (outw(reg,PORT+L_ADDRREG),inw(PORT+L_DATAREG))
        !           175: #define writedatareg(val) { writereg(val,CSR0); }
        !           176: #endif
        !           177: 
        !           178: static unsigned char ni_vendor[] = { 0x02,0x07,0x01 };
        !           179: 
        !           180: static struct card {
        !           181:        unsigned char id0,id1;
        !           182:        short id_offset;
        !           183:        short total_size;
        !           184:        short cmd_offset;
        !           185:        short addr_offset;
        !           186:        unsigned char *vendor_id;
        !           187:        char *cardname;
        !           188:        unsigned char config;
        !           189: } cards[] = {
        !           190:        { NI65_ID0,NI65_ID1,0x0e,0x10,0x0,0x8,ni_vendor,"ni6510", 0x1 } ,
        !           191:        { NI65_EB_ID0,NI65_EB_ID1,0x0e,0x18,0x10,0x0,ni_vendor,"ni6510 EtherBlaster", 0x2 } ,
        !           192:        { NE2100_ID0,NE2100_ID1,0x0e,0x18,0x10,0x0,NULL,"generic NE2100", 0x0 }
        !           193: };
        !           194: #define NUM_CARDS 3
        !           195: 
        !           196: struct priv 
        !           197: {
        !           198:   struct rmd rmdhead[RMDNUM];
        !           199:   struct tmd tmdhead[TMDNUM];
        !           200:   struct init_block ib; 
        !           201:   int rmdnum;
        !           202:   int tmdnum,tmdlast;
        !           203: #ifdef RCV_VIA_SKB
        !           204:   struct sk_buff *recv_skb[RMDNUM];
        !           205: #else
        !           206:   void *recvbounce[RMDNUM];
        !           207: #endif
        !           208: #ifdef XMT_VIA_SKB
        !           209:   struct sk_buff *tmd_skb[TMDNUM];
        !           210: #endif
        !           211:   void *tmdbounce[TMDNUM];
        !           212:   int tmdbouncenum;
        !           213:   int lock,xmit_queued;
        !           214:   struct enet_statistics stats;
        !           215:   void *self;
        !           216:   int cmdr_addr;
        !           217:   int cardno;
        !           218:   int features;
        !           219: }; 
        !           220: 
        !           221: static int  ni65_probe1(struct device *dev,int);
        !           222: static void ni65_interrupt(int irq, void * dev_id, struct pt_regs *regs);
        !           223: static void ni65_recv_intr(struct device *dev,int);
        !           224: static void ni65_xmit_intr(struct device *dev,int);
        !           225: static int  ni65_open(struct device *dev);
        !           226: static int  ni65_lance_reinit(struct device *dev);
        !           227: static void ni65_init_lance(struct priv *p,unsigned char*,int,int);
        !           228: static int  ni65_send_packet(struct sk_buff *skb, struct device *dev);
        !           229: static int  ni65_close(struct device *dev);
        !           230: static int  ni65_alloc_buffer(struct device *dev);
        !           231: static void ni65_free_buffer(struct priv *p);
        !           232: static struct enet_statistics *ni65_get_stats(struct device *);
        !           233: static void set_multicast_list(struct device *dev);
        !           234: 
        !           235: static int irqtab[] = { 9,12,15,5 }; /* irq config-translate */
        !           236: static int dmatab[] = { 0,3,5,6,7 }; /* dma config-translate and autodetect */
        !           237: 
        !           238: static int debuglevel = 1;
        !           239: 
        !           240: /*
        !           241:  * set 'performance' registers .. we must STOP lance for that
        !           242:  */
        !           243: static void ni65_set_performance(struct priv *p)
        !           244: {
        !           245:   writereg(CSR0_STOP | CSR0_CLRALL,CSR0); /* STOP */
        !           246: 
        !           247:   if( !(cards[p->cardno].config & 0x02) )
        !           248:     return;
        !           249:  
        !           250:   outw(80,PORT+L_ADDRREG);
        !           251:   if(inw(PORT+L_ADDRREG) != 80)
        !           252:     return;
        !           253:  
        !           254:   writereg( (csr80 & 0x3fff) ,80); /* FIFO watermarks */
        !           255:   outw(0,PORT+L_ADDRREG);
        !           256:   outw((short)isa0,PORT+L_BUSIF); /* write ISA 0: DMA_R : isa0 * 50ns */
        !           257:   outw(1,PORT+L_ADDRREG);
        !           258:   outw((short)isa1,PORT+L_BUSIF); /* write ISA 1: DMA_W : isa1 * 50ns  */
        !           259: 
        !           260:   outw(CSR0,PORT+L_ADDRREG);   /* switch back to CSR0 */
        !           261: }
        !           262: 
        !           263: /*
        !           264:  * open interface (up)
        !           265:  */
        !           266: static int ni65_open(struct device *dev)
        !           267: {
        !           268:   struct priv *p = (struct priv *) dev->priv;
        !           269:   int irqval = request_irq(dev->irq, &ni65_interrupt,0,
        !           270:                         cards[p->cardno].cardname,NULL);
        !           271:   if (irqval) {
        !           272:     printk ("%s: unable to get IRQ %d (irqval=%d).\n", 
        !           273:               dev->name,dev->irq, irqval);
        !           274:     return -EAGAIN;
        !           275:   }
        !           276:   irq2dev_map[dev->irq] = dev;
        !           277: 
        !           278:   if(ni65_lance_reinit(dev))
        !           279:   {
        !           280:     dev->tbusy     = 0;
        !           281:     dev->interrupt = 0;
        !           282:     dev->start     = 1;
        !           283:     MOD_INC_USE_COUNT;
        !           284:     return 0;
        !           285:   }
        !           286:   else
        !           287:   {
        !           288:     irq2dev_map[dev->irq] = NULL;
        !           289:     free_irq(dev->irq,NULL);
        !           290:     dev->start = 0;
        !           291:     return -EAGAIN;
        !           292:   }
        !           293: }
        !           294: 
        !           295: /*
        !           296:  * close interface (down)
        !           297:  */
        !           298: static int ni65_close(struct device *dev)
        !           299: {
        !           300:   struct priv *p = (struct priv *) dev->priv;
        !           301: 
        !           302:   outw(inw(PORT+L_RESET),PORT+L_RESET); /* that's the hard way */
        !           303: 
        !           304: #ifdef XMT_VIA_SKB
        !           305:   {
        !           306:     int i;
        !           307:     for(i=0;i<TMDNUM;i++)
        !           308:     {
        !           309:       if(p->tmd_skb[i]) {
        !           310:         dev_kfree_skb(p->tmd_skb[i],FREE_WRITE);
        !           311:         p->tmd_skb[i] = NULL;
        !           312:       }
        !           313:     }
        !           314:   }
        !           315: #endif
        !           316:   irq2dev_map[dev->irq] = NULL;
        !           317:   free_irq(dev->irq,NULL);
        !           318:   dev->tbusy = 1;
        !           319:   dev->start = 0;
        !           320:   MOD_DEC_USE_COUNT;
        !           321:   return 0; 
        !           322: }
        !           323: 
        !           324: /* 
        !           325:  * Probe The Card (not the lance-chip) 
        !           326:  */ 
        !           327: #ifdef MODULE
        !           328: static
        !           329: #endif
        !           330: int ni65_probe(struct device *dev)
        !           331: {
        !           332:   int *port;
        !           333:   static int ports[] = {0x360,0x300,0x320,0x340, 0};
        !           334: 
        !           335:   if (dev->base_addr > 0x1ff)          /* Check a single specified location. */
        !           336:      return ni65_probe1(dev, dev->base_addr);
        !           337:   else if (dev->base_addr > 0)         /* Don't probe at all. */
        !           338:      return -ENXIO;
        !           339: 
        !           340:   for (port = ports; *port; port++) 
        !           341:   {
        !           342:     if (ni65_probe1(dev, *port) == 0)
        !           343:        return 0;
        !           344:   }
        !           345: 
        !           346:   return -ENODEV;
        !           347: }
        !           348: 
        !           349: /*
        !           350:  * this is the real card probe .. 
        !           351:  */
        !           352: static int ni65_probe1(struct device *dev,int ioaddr)
        !           353: {
        !           354:   int i,j;
        !           355:   struct priv *p; 
        !           356: 
        !           357:   for(i=0;i<NUM_CARDS;i++) {
        !           358:     if(check_region(ioaddr, cards[i].total_size))
        !           359:       continue;
        !           360:     if(cards[i].id_offset >= 0) {
        !           361:       if(inb(ioaddr+cards[i].id_offset+0) != cards[i].id0 ||
        !           362:          inb(ioaddr+cards[i].id_offset+1) != cards[i].id1) {
        !           363:          continue;
        !           364:       }
        !           365:     }
        !           366:     if(cards[i].vendor_id) {
        !           367:       for(j=0;j<3;j++)
        !           368:         if(inb(ioaddr+cards[i].addr_offset+j) != cards[i].vendor_id[j])
        !           369:           continue;
        !           370:     }
        !           371:     break;
        !           372:   }
        !           373:   if(i == NUM_CARDS)
        !           374:     return -ENODEV;
        !           375: 
        !           376:   for(j=0;j<6;j++)
        !           377:     dev->dev_addr[j] = inb(ioaddr+cards[i].addr_offset+j);
        !           378: 
        !           379:   if( (j=ni65_alloc_buffer(dev)) < 0)
        !           380:     return j;
        !           381:   p = (struct priv *) dev->priv;
        !           382:   p->cmdr_addr = ioaddr + cards[i].cmd_offset;
        !           383:   p->cardno = i;
        !           384: 
        !           385:   printk("%s: %s found at %#3x, ", dev->name, cards[p->cardno].cardname , ioaddr);
        !           386: 
        !           387:   outw(inw(PORT+L_RESET),PORT+L_RESET); /* first: reset the card */
        !           388:   if( (j=readreg(CSR0)) != 0x4) {
        !           389:      printk(KERN_ERR "can't RESET card: %04x\n",j);
        !           390:      ni65_free_buffer(p);
        !           391:      return -EAGAIN;
        !           392:   }
        !           393: 
        !           394:   outw(88,PORT+L_ADDRREG);
        !           395:   if(inw(PORT+L_ADDRREG) == 88) {
        !           396:     unsigned long v;
        !           397:     v = inw(PORT+L_DATAREG);
        !           398:     v <<= 16;
        !           399:     outw(89,PORT+L_ADDRREG);
        !           400:     v |= inw(PORT+L_DATAREG);
        !           401:     printk("Version %#08lx, ",v);
        !           402:     p->features = INIT_RING_BEFORE_START;
        !           403:   }
        !           404:   else {
        !           405:     printk("ancient LANCE, ");
        !           406:     p->features = 0x0;
        !           407:   }
        !           408: 
        !           409:   if(test_bit(0,&cards[i].config)) {
        !           410:     dev->irq = irqtab[(inw(ioaddr+L_CONFIG)>>2)&3];
        !           411:     dev->dma = dmatab[inw(ioaddr+L_CONFIG)&3];
        !           412:     printk("IRQ %d (from card), DMA %d (from card).\n",dev->irq,dev->dma);
        !           413:   }
        !           414:   else {
        !           415:     if(dev->dma == 0) {
        !           416:                /* 'stuck test' from lance.c */
        !           417:       int dma_channels = ((inb(DMA1_STAT_REG) >> 4) & 0x0f) | (inb(DMA2_STAT_REG) & 0xf0);
        !           418:       for(i=1;i<5;i++) {
        !           419:         int dma = dmatab[i];
        !           420:         if(test_bit(dma,&dma_channels) || request_dma(dma,"ni6510"))
        !           421:           continue;
        !           422:         disable_dma(dma);
        !           423:         set_dma_mode(dma,DMA_MODE_CASCADE);
        !           424:         enable_dma(dma);
        !           425:         ni65_init_lance(p,dev->dev_addr,0,0); /* trigger memory access */
        !           426:         disable_dma(dma);
        !           427:         free_dma(dma);
        !           428:         if(readreg(CSR0) & CSR0_IDON)
        !           429:           break;
        !           430:       }
        !           431:       if(i == 5) {
        !           432:         printk("Can't detect DMA channel!\n");
        !           433:         ni65_free_buffer(p);
        !           434:         return -EAGAIN;
        !           435:       }
        !           436:       dev->dma = dmatab[i];
        !           437:       printk("DMA %d (autodetected), ",dev->dma);
        !           438:     }
        !           439:     else
        !           440:       printk("DMA %d (assigned), ",dev->dma);
        !           441: 
        !           442:     if(dev->irq < 2)
        !           443:     {
        !           444:       ni65_init_lance(p,dev->dev_addr,0,0);
        !           445:       autoirq_setup(0);
        !           446:       writereg(CSR0_INIT|CSR0_INEA,CSR0); /* trigger interrupt */
        !           447: 
        !           448:       if(!(dev->irq = autoirq_report(2)))
        !           449:       {
        !           450:         printk("Failed to detect IRQ line!\n");
        !           451:         ni65_free_buffer(p);
        !           452:         return -EAGAIN;
        !           453:       }
        !           454:       printk("IRQ %d (autodetected).\n",dev->irq);
        !           455:     }
        !           456:     else
        !           457:       printk("IRQ %d (assigned).\n",dev->irq);
        !           458:   }
        !           459: 
        !           460:   if(request_dma(dev->dma, cards[p->cardno].cardname ) != 0)
        !           461:   {
        !           462:     printk("%s: Can't request dma-channel %d\n",dev->name,(int) dev->dma);
        !           463:     ni65_free_buffer(p);
        !           464:     return -EAGAIN;
        !           465:   }
        !           466: 
        !           467:   /* 
        !           468:    * Grab the region so we can find another board. 
        !           469:    */
        !           470:   request_region(ioaddr,cards[p->cardno].total_size,cards[p->cardno].cardname);
        !           471: 
        !           472:   dev->base_addr = ioaddr;
        !           473: 
        !           474:   dev->open               = ni65_open;
        !           475:   dev->stop               = ni65_close;
        !           476:   dev->hard_start_xmit    = ni65_send_packet;
        !           477:   dev->get_stats          = ni65_get_stats;
        !           478:   dev->set_multicast_list = set_multicast_list;
        !           479: 
        !           480:   ether_setup(dev);
        !           481: 
        !           482:   dev->interrupt      = 0;
        !           483:   dev->tbusy          = 0;
        !           484:   dev->start          = 0;
        !           485: 
        !           486:   return 0; /* everything is OK */
        !           487: }
        !           488: 
        !           489: /*
        !           490:  * set lance register and trigger init 
        !           491:  */
        !           492: static void ni65_init_lance(struct priv *p,unsigned char *daddr,int filter,int mode) 
        !           493: {
        !           494:   int i;
        !           495:   u32 pib;
        !           496: 
        !           497:   writereg(CSR0_CLRALL|CSR0_STOP,CSR0);
        !           498: 
        !           499:   for(i=0;i<6;i++)
        !           500:     p->ib.eaddr[i] = daddr[i];
        !           501: 
        !           502:   for(i=0;i<8;i++)
        !           503:     p->ib.filter[i] = filter;
        !           504:   p->ib.mode = mode;
        !           505: 
        !           506:   p->ib.trp = (u32) virt_to_bus(p->tmdhead) | TMDNUMMASK;
        !           507:   p->ib.rrp = (u32) virt_to_bus(p->rmdhead) | RMDNUMMASK;
        !           508:   writereg(0,CSR3);  /* busmaster/no word-swap */
        !           509:   pib = (u32) virt_to_bus(&p->ib);
        !           510:   writereg(pib & 0xffff,CSR1);
        !           511:   writereg(pib >> 16,CSR2);
        !           512: 
        !           513:   writereg(CSR0_INIT,CSR0); /* this changes L_ADDRREG to CSR0 */
        !           514: 
        !           515:   for(i=0;i<32;i++)
        !           516:   {
        !           517:     udelay(4000);
        !           518:     if(inw(PORT+L_DATAREG) & (CSR0_IDON | CSR0_MERR) )
        !           519:       break; /* init ok ? */
        !           520:   }
        !           521: }
        !           522: 
        !           523: /*
        !           524:  * allocate memory area and check the 16MB border
        !           525:  */
        !           526: static void *ni65_alloc_mem(struct device *dev,char *what,int size,int type)
        !           527: {
        !           528:   struct sk_buff *skb=NULL;
        !           529:   unsigned char *ptr;
        !           530:   void *ret;
        !           531: 
        !           532:   if(type) {
        !           533:     ret = skb = alloc_skb(2+16+size,GFP_KERNEL|GFP_DMA);
        !           534:     if(!skb) {
        !           535:       printk("%s: unable to allocate %s memory.\n",dev->name,what);
        !           536:       return NULL;
        !           537:     }
        !           538:     skb->dev = dev;
        !           539:     skb_reserve(skb,2+16);
        !           540:     skb_put(skb,R_BUF_SIZE);   /* grab the whole space .. (not necessary) */
        !           541:     ptr = skb->data;
        !           542:   }
        !           543:   else {
        !           544:     ret = ptr = kmalloc(T_BUF_SIZE,GFP_KERNEL | GFP_DMA);
        !           545:     if(!ret) {
        !           546:       printk("%s: unable to allocate %s memory.\n",dev->name,what);
        !           547:       return NULL;
        !           548:     }
        !           549:   }
        !           550:   if( (u32) virt_to_bus(ptr+size) > 0x1000000) {
        !           551:     printk("%s: unable to allocate %s memory in lower 16MB!\n",dev->name,what);
        !           552:     if(type)
        !           553:       kfree_skb(skb,FREE_WRITE);
        !           554:     else
        !           555:       kfree(ptr);
        !           556:     return NULL;
        !           557:   }
        !           558:   return ret;
        !           559: }
        !           560: 
        !           561: /*
        !           562:  * allocate all memory structures .. send/recv buffers etc ...
        !           563:  */
        !           564: static int ni65_alloc_buffer(struct device *dev)
        !           565: {
        !           566:   unsigned char *ptr;
        !           567:   struct priv *p;
        !           568:   int i;
        !           569:  
        !           570:   /* 
        !           571:    * we need 8-aligned memory ..
        !           572:    */
        !           573:   ptr = ni65_alloc_mem(dev,"BUFFER",sizeof(struct priv)+8,0);
        !           574:   if(!ptr)
        !           575:     return -ENOMEM;
        !           576: 
        !           577:   p = dev->priv = (struct priv *) (((unsigned long) ptr + 7) & ~0x7);
        !           578:   memset((char *) dev->priv,0,sizeof(struct priv));
        !           579:   p->self = ptr;
        !           580: 
        !           581:   for(i=0;i<TMDNUM;i++)
        !           582:   {
        !           583: #ifdef XMT_VIA_SKB
        !           584:     p->tmd_skb[i] = NULL;
        !           585: #endif
        !           586:     p->tmdbounce[i] = ni65_alloc_mem(dev,"XMIT",T_BUF_SIZE,0);
        !           587:     if(!p->tmdbounce[i]) {
        !           588:       ni65_free_buffer(p);
        !           589:       return -ENOMEM;
        !           590:     }
        !           591:   }
        !           592: 
        !           593:   for(i=0;i<RMDNUM;i++)
        !           594:   {
        !           595: #ifdef RCV_VIA_SKB
        !           596:     p->recv_skb[i] = ni65_alloc_mem(dev,"RECV",R_BUF_SIZE,1);
        !           597:     if(!p->recv_skb[i]) {
        !           598:       ni65_free_buffer(p);
        !           599:       return -ENOMEM;
        !           600:     }
        !           601: #else
        !           602:     p->recvbounce[i] = ni65_alloc_mem(dev,"RECV",R_BUF_SIZE,0);
        !           603:     if(!p->recvbounce[i]) {
        !           604:       ni65_free_buffer(p);
        !           605:       return -ENOMEM;
        !           606:     }
        !           607: #endif
        !           608:   }
        !           609: 
        !           610:   return 0; /* everything is OK */
        !           611: }
        !           612: 
        !           613: /*
        !           614:  * free buffers and private struct 
        !           615:  */
        !           616: static void ni65_free_buffer(struct priv *p)
        !           617: {
        !           618:   int i;
        !           619: 
        !           620:   if(!p)
        !           621:     return;
        !           622: 
        !           623:   for(i=0;i<TMDNUM;i++) {
        !           624:     if(p->tmdbounce[i])
        !           625:       kfree(p->tmdbounce[i]);
        !           626: #ifdef XMT_VIA_SKB
        !           627:     if(p->tmd_skb[i])
        !           628:       dev_kfree_skb(p->tmd_skb[i],FREE_WRITE);
        !           629: #endif
        !           630:   }
        !           631: 
        !           632:   for(i=0;i<RMDNUM;i++)
        !           633:   {
        !           634: #ifdef RCV_VIA_SKB
        !           635:     if(p->recv_skb[i])
        !           636:       dev_kfree_skb(p->recv_skb[i],FREE_WRITE);
        !           637: #else
        !           638:     if(p->recvbounce[i])
        !           639:       kfree(p->recvbounce[i]);
        !           640: #endif
        !           641:   }
        !           642:   if(p->self)
        !           643:     kfree(p->self);
        !           644: }
        !           645: 
        !           646: 
        !           647: /*
        !           648:  * stop and (re)start lance .. e.g after an error
        !           649:  */
        !           650: static void ni65_stop_start(struct device *dev,struct priv *p)
        !           651: {
        !           652:   int csr0 = CSR0_INEA;
        !           653: 
        !           654:   writedatareg(CSR0_STOP);
        !           655: 
        !           656:   if(debuglevel > 1)
        !           657:     printk("ni65_stop_start\n");
        !           658: 
        !           659:   if(p->features & INIT_RING_BEFORE_START) {
        !           660:     int i;
        !           661: #ifdef XMT_VIA_SKB
        !           662:     struct sk_buff *skb_save[TMDNUM];
        !           663: #endif
        !           664:     unsigned long buffer[TMDNUM];
        !           665:     short blen[TMDNUM];
        !           666: 
        !           667:     if(p->xmit_queued) {
        !           668:       while(1) {
        !           669:         if((p->tmdhead[p->tmdlast].u.s.status & XMIT_OWN))
        !           670:           break;
        !           671:         p->tmdlast = (p->tmdlast + 1) & (TMDNUM-1);
        !           672:         if(p->tmdlast == p->tmdnum)
        !           673:           break;
        !           674:       }
        !           675:     }
        !           676:     
        !           677:     for(i=0;i<TMDNUM;i++) {
        !           678:       struct tmd *tmdp = p->tmdhead + i;
        !           679: #ifdef XMT_VIA_SKB
        !           680:       skb_save[i] = p->tmd_skb[i];
        !           681: #endif
        !           682:       buffer[i] = (u32) bus_to_virt(tmdp->u.buffer);
        !           683:       blen[i] = tmdp->blen;
        !           684:       tmdp->u.s.status = 0x0;
        !           685:     }
        !           686: 
        !           687:     for(i=0;i<RMDNUM;i++) {
        !           688:       struct rmd *rmdp = p->rmdhead + i;
        !           689:       rmdp->u.s.status = RCV_OWN;
        !           690:     }
        !           691:     p->tmdnum = p->xmit_queued = 0;
        !           692:     writedatareg(CSR0_STRT | csr0);
        !           693: 
        !           694:     for(i=0;i<TMDNUM;i++) {
        !           695:       int num = (i + p->tmdlast) & (TMDNUM-1);
        !           696:       p->tmdhead[i].u.buffer = (u32) virt_to_bus((char *)buffer[num]); /* status is part of buffer field */
        !           697:       p->tmdhead[i].blen = blen[num];
        !           698:       if(p->tmdhead[i].u.s.status & XMIT_OWN) {
        !           699:          p->tmdnum = (p->tmdnum + 1) & (TMDNUM-1);
        !           700:          p->xmit_queued = 1;
        !           701:         writedatareg(CSR0_TDMD | CSR0_INEA | csr0);
        !           702:       }
        !           703: #ifdef XMT_VIA_SKB
        !           704:       p->tmd_skb[i] = skb_save[num];
        !           705: #endif
        !           706:     }
        !           707:     p->rmdnum = p->tmdlast = 0;
        !           708:     if(!p->lock)
        !           709:       dev->tbusy = (p->tmdnum || !p->xmit_queued) ? 0 : 1;
        !           710:     dev->trans_start = jiffies;
        !           711:   } 
        !           712:   else
        !           713:     writedatareg(CSR0_STRT | csr0);
        !           714: }
        !           715: 
        !           716: /* 
        !           717:  * init lance (write init-values .. init-buffers) (open-helper)
        !           718:  */
        !           719: static int ni65_lance_reinit(struct device *dev)
        !           720: {
        !           721:    int i;
        !           722:    struct priv *p = (struct priv *) dev->priv;
        !           723: 
        !           724:    p->lock = 0;
        !           725:    p->xmit_queued = 0;
        !           726: 
        !           727:    disable_dma(dev->dma); /* I've never worked with dma, but we do it like the packetdriver */
        !           728:    set_dma_mode(dev->dma,DMA_MODE_CASCADE);
        !           729:    enable_dma(dev->dma); 
        !           730: 
        !           731:    outw(inw(PORT+L_RESET),PORT+L_RESET); /* first: reset the card */
        !           732:    if( (i=readreg(CSR0) ) != 0x4)
        !           733:    {
        !           734:      printk(KERN_ERR "%s: can't RESET %s card: %04x\n",dev->name,
        !           735:               cards[p->cardno].cardname,(int) i);
        !           736:      disable_dma(dev->dma);
        !           737:      return 0;
        !           738:    }
        !           739: 
        !           740:    p->rmdnum = p->tmdnum = p->tmdlast = p->tmdbouncenum = 0;
        !           741:    for(i=0;i<TMDNUM;i++)
        !           742:    {
        !           743:      struct tmd *tmdp = p->tmdhead + i;
        !           744: #ifdef XMT_VIA_SKB
        !           745:      if(p->tmd_skb[i]) {
        !           746:        dev_kfree_skb(p->tmd_skb[i],FREE_WRITE);
        !           747:        p->tmd_skb[i] = NULL;
        !           748:      }
        !           749: #endif
        !           750:      tmdp->u.buffer = 0x0;
        !           751:      tmdp->u.s.status = XMIT_START | XMIT_END;
        !           752:      tmdp->blen = tmdp->status2 = 0;
        !           753:    }
        !           754: 
        !           755:    for(i=0;i<RMDNUM;i++)
        !           756:    {
        !           757:      struct rmd *rmdp = p->rmdhead + i;
        !           758: #ifdef RCV_VIA_SKB
        !           759:      rmdp->u.buffer = (u32) virt_to_bus(p->recv_skb[i]->data);
        !           760: #else
        !           761:      rmdp->u.buffer = (u32) virt_to_bus(p->recvbounce[i]);
        !           762: #endif
        !           763:      rmdp->blen = -(R_BUF_SIZE-8);
        !           764:      rmdp->mlen = 0;
        !           765:      rmdp->u.s.status = RCV_OWN;
        !           766:    }
        !           767:    
        !           768:    if(dev->flags & IFF_PROMISC)
        !           769:      ni65_init_lance(p,dev->dev_addr,0x00,M_PROM);
        !           770:    else if(dev->mc_count || dev->flags & IFF_ALLMULTI)
        !           771:      ni65_init_lance(p,dev->dev_addr,0xff,0x0);
        !           772:    else 
        !           773:      ni65_init_lance(p,dev->dev_addr,0x00,0x00);
        !           774: 
        !           775:   /*
        !           776:    * ni65_set_lance_mem() sets L_ADDRREG to CSR0
        !           777:    * NOW, WE WILL NEVER CHANGE THE L_ADDRREG, CSR0 IS ALWAYS SELECTED 
        !           778:    */
        !           779: 
        !           780:    if(inw(PORT+L_DATAREG) & CSR0_IDON)  {
        !           781:      ni65_set_performance(p);
        !           782:            /* init OK: start lance , enable interrupts */
        !           783:      writedatareg(CSR0_CLRALL | CSR0_INEA | CSR0_STRT);
        !           784:      return 1; /* ->OK */
        !           785:    }
        !           786:    printk(KERN_ERR "%s: can't init lance, status: %04x\n",dev->name,(int) inw(PORT+L_DATAREG));
        !           787:    disable_dma(dev->dma);
        !           788:    return 0; /* ->Error */
        !           789: }
        !           790:  
        !           791: /* 
        !           792:  * interrupt handler  
        !           793:  */
        !           794: static void ni65_interrupt(int irq, void * dev_id, struct pt_regs * regs)
        !           795: {
        !           796:   int csr0;
        !           797:   struct device *dev = (struct device *) irq2dev_map[irq];
        !           798:   struct priv *p;
        !           799:   int bcnt = 32;
        !           800: 
        !           801:   if (dev == NULL) {
        !           802:     printk (KERN_ERR "ni65_interrupt(): irq %d for unknown device.\n", irq);
        !           803:     return;
        !           804:   }
        !           805: 
        !           806:   if(set_bit(0,(int *) &dev->interrupt)) {
        !           807:     printk("ni65: oops .. interrupt while proceeding interrupt\n");
        !           808:     return;
        !           809:   }
        !           810:   p = (struct priv *) dev->priv;
        !           811: 
        !           812:   while(--bcnt) {
        !           813:     csr0 = inw(PORT+L_DATAREG);
        !           814: 
        !           815: #if 0
        !           816:     writedatareg( (csr0 & CSR0_CLRALL) ); /* ack interrupts, disable int. */
        !           817: #else
        !           818:     writedatareg( (csr0 & CSR0_CLRALL) | CSR0_INEA ); /* ack interrupts, interrupts enabled */
        !           819: #endif
        !           820: 
        !           821:     if(!(csr0 & (CSR0_ERR | CSR0_RINT | CSR0_TINT)))
        !           822:       break;
        !           823: 
        !           824:     if(csr0 & CSR0_RINT) /* RECV-int? */
        !           825:       ni65_recv_intr(dev,csr0);
        !           826:     if(csr0 & CSR0_TINT) /* XMIT-int? */
        !           827:       ni65_xmit_intr(dev,csr0);
        !           828: 
        !           829:     if(csr0 & CSR0_ERR)
        !           830:     {
        !           831:       struct priv *p = (struct priv *) dev->priv;
        !           832:       if(debuglevel > 1)
        !           833:         printk("%s: general error: %04x.\n",dev->name,csr0);
        !           834:       if(csr0 & CSR0_BABL)
        !           835:         p->stats.tx_errors++;
        !           836:       if(csr0 & CSR0_MISS) {
        !           837:         int i;
        !           838:         for(i=0;i<RMDNUM;i++)
        !           839:           printk("%02x ",p->rmdhead[i].u.s.status);
        !           840:         printk("\n");
        !           841:         p->stats.rx_errors++;
        !           842:       }
        !           843:       if(csr0 & CSR0_MERR) {
        !           844:         if(debuglevel > 1)
        !           845:           printk("%s: Ooops .. memory error: %04x.\n",dev->name,csr0);
        !           846:         ni65_stop_start(dev,p);
        !           847:       }
        !           848:     }
        !           849:   }
        !           850: 
        !           851: #ifdef RCV_PARANOIA_CHECK
        !           852: {
        !           853:  int j;
        !           854:  for(j=0;j<RMDNUM;j++)
        !           855:  {
        !           856:   struct priv *p = (struct priv *) dev->priv;
        !           857:   int i,k,num1,num2;
        !           858:   for(i=RMDNUM-1;i>0;i--) {
        !           859:      num2 = (p->rmdnum + i) & (RMDNUM-1);
        !           860:      if(!(p->rmdhead[num2].u.s.status & RCV_OWN))
        !           861:         break;
        !           862:   }
        !           863: 
        !           864:   if(i) {
        !           865:     for(k=0;k<RMDNUM;k++) {
        !           866:       num1 = (p->rmdnum + k) & (RMDNUM-1);
        !           867:       if(!(p->rmdhead[num1].u.s.status & RCV_OWN))
        !           868:         break;
        !           869:     }
        !           870:     if(!k)
        !           871:       break;
        !           872: 
        !           873:     if(debuglevel > 0)
        !           874:     {
        !           875:       char buf[256],*buf1;
        !           876:       int k;
        !           877:       buf1 = buf;
        !           878:       for(k=0;k<RMDNUM;k++) {
        !           879:         sprintf(buf1,"%02x ",(p->rmdhead[k].u.s.status)); /* & RCV_OWN) ); */
        !           880:         buf1 += 3;
        !           881:       }
        !           882:       *buf1 = 0;
        !           883:       printk(KERN_ERR "%s: Ooops, receive ring corrupted %2d %2d | %s\n",dev->name,p->rmdnum,i,buf);
        !           884:     }
        !           885: 
        !           886:     p->rmdnum = num1;
        !           887:     ni65_recv_intr(dev,csr0);
        !           888:     if((p->rmdhead[num2].u.s.status & RCV_OWN))
        !           889:       break;   /* ok, we are 'in sync' again */
        !           890:   }
        !           891:   else
        !           892:     break;
        !           893:  }
        !           894: }
        !           895: #endif
        !           896: 
        !           897:   if( (csr0 & (CSR0_RXON | CSR0_TXON)) != (CSR0_RXON | CSR0_TXON) ) {
        !           898:     printk("%s: RX or TX was offline -> restart\n",dev->name);
        !           899:     ni65_stop_start(dev,p);
        !           900:   }
        !           901:   else
        !           902:     writedatareg(CSR0_INEA);
        !           903: 
        !           904:   dev->interrupt = 0;
        !           905: 
        !           906:   return;
        !           907: }
        !           908: 
        !           909: /*
        !           910:  * We have received an Xmit-Interrupt ..
        !           911:  * send a new packet if necessary
        !           912:  */
        !           913: static void ni65_xmit_intr(struct device *dev,int csr0)
        !           914: {
        !           915:   struct priv *p = (struct priv *) dev->priv;
        !           916: 
        !           917:   while(p->xmit_queued)
        !           918:   {
        !           919:     struct tmd *tmdp = p->tmdhead + p->tmdlast;
        !           920:     int tmdstat = tmdp->u.s.status;
        !           921: 
        !           922:     if(tmdstat & XMIT_OWN)
        !           923:       break;
        !           924: 
        !           925:     if(tmdstat & XMIT_ERR)
        !           926:     {
        !           927: #if 0
        !           928:       if(tmdp->status2 & XMIT_TDRMASK && debuglevel > 3)
        !           929:         printk(KERN_ERR "%s: tdr-problems (e.g. no resistor)\n",dev->name);
        !           930: #endif
        !           931:      /* checking some errors */
        !           932:       if(tmdp->status2 & XMIT_RTRY)
        !           933:         p->stats.tx_aborted_errors++;
        !           934:       if(tmdp->status2 & XMIT_LCAR)
        !           935:         p->stats.tx_carrier_errors++;
        !           936:       if(tmdp->status2 & (XMIT_BUFF | XMIT_UFLO )) {
        !           937:                /* this stops the xmitter */
        !           938:         p->stats.tx_fifo_errors++;
        !           939:         if(debuglevel > 0)
        !           940:           printk(KERN_ERR "%s: Xmit FIFO/BUFF error\n",dev->name);
        !           941:         if(p->features & INIT_RING_BEFORE_START) {
        !           942:           tmdp->u.s.status = XMIT_OWN | XMIT_START | XMIT_END; /* test: resend this frame */
        !           943:           ni65_stop_start(dev,p);
        !           944:           break;       /* no more Xmit processing .. */
        !           945:         }
        !           946:         else
        !           947:          ni65_stop_start(dev,p);
        !           948:       }
        !           949:       if(debuglevel > 2)
        !           950:         printk(KERN_ERR "%s: xmit-error: %04x %02x-%04x\n",dev->name,csr0,(int) tmdstat,(int) tmdp->status2);
        !           951:       if(!(csr0 & CSR0_BABL)) /* don't count errors twice */
        !           952:         p->stats.tx_errors++;
        !           953:       tmdp->status2 = 0;
        !           954:     }
        !           955:     else
        !           956:       p->stats.tx_packets++;
        !           957: 
        !           958: #ifdef XMT_VIA_SKB
        !           959:     if(p->tmd_skb[p->tmdlast]) {
        !           960:        dev_kfree_skb(p->tmd_skb[p->tmdlast],FREE_WRITE);
        !           961:        p->tmd_skb[p->tmdlast] = NULL;
        !           962:     }
        !           963: #endif
        !           964: 
        !           965:     p->tmdlast = (p->tmdlast + 1) & (TMDNUM-1);
        !           966:     if(p->tmdlast == p->tmdnum)
        !           967:       p->xmit_queued = 0;
        !           968:   }
        !           969:   dev->tbusy = 0;
        !           970:   mark_bh(NET_BH);
        !           971: }
        !           972: 
        !           973: /*
        !           974:  * We have received a packet
        !           975:  */
        !           976: static void ni65_recv_intr(struct device *dev,int csr0)
        !           977: {
        !           978:   struct rmd *rmdp; 
        !           979:   int rmdstat,len;
        !           980:   int cnt=0;
        !           981:   struct priv *p = (struct priv *) dev->priv;
        !           982: 
        !           983:   rmdp = p->rmdhead + p->rmdnum;
        !           984:   while(!( (rmdstat = rmdp->u.s.status) & RCV_OWN))
        !           985:   {
        !           986:     cnt++;
        !           987:     if( (rmdstat & (RCV_START | RCV_END | RCV_ERR)) != (RCV_START | RCV_END) ) /* error or oversized? */ 
        !           988:     {
        !           989:       if(!(rmdstat & RCV_ERR)) {
        !           990:         if(rmdstat & RCV_START)
        !           991:         {
        !           992:           p->stats.rx_length_errors++;
        !           993:           printk(KERN_ERR "%s: recv, packet too long: %d\n",dev->name,rmdp->mlen & 0x0fff);
        !           994:         }
        !           995:       }
        !           996:       else {
        !           997:         if(debuglevel > 2)
        !           998:           printk(KERN_ERR "%s: receive-error: %04x, lance-status: %04x/%04x\n",
        !           999:                   dev->name,(int) rmdstat,csr0,(int) inw(PORT+L_DATAREG) );
        !          1000:         if(rmdstat & RCV_FRAM)
        !          1001:           p->stats.rx_frame_errors++;
        !          1002:         if(rmdstat & RCV_OFLO)
        !          1003:           p->stats.rx_over_errors++;
        !          1004:         if(rmdstat & RCV_CRC) 
        !          1005:           p->stats.rx_crc_errors++;
        !          1006:         if(rmdstat & RCV_BUF_ERR)
        !          1007:           p->stats.rx_fifo_errors++;
        !          1008:       }
        !          1009:       if(!(csr0 & CSR0_MISS)) /* don't count errors twice */
        !          1010:         p->stats.rx_errors++;
        !          1011:     }
        !          1012:     else if( (len = (rmdp->mlen & 0x0fff) - 4) >= 60)
        !          1013:     {
        !          1014: #ifdef RCV_VIA_SKB
        !          1015:       struct sk_buff *skb = alloc_skb(R_BUF_SIZE+2+16,GFP_ATOMIC);
        !          1016:       if (skb)
        !          1017:         skb_reserve(skb,16);
        !          1018: #else
        !          1019:       struct sk_buff *skb = dev_alloc_skb(len+2);
        !          1020: #endif
        !          1021:       if(skb)
        !          1022:       {
        !          1023:         skb_reserve(skb,2);
        !          1024:        skb->dev = dev;
        !          1025: #ifdef RCV_VIA_SKB
        !          1026:         if( (unsigned long) (skb->data + R_BUF_SIZE) > 0x1000000) {
        !          1027:           skb_put(skb,len);
        !          1028:           eth_copy_and_sum(skb, (unsigned char *)(p->recv_skb[p->rmdnum]->data),len,0);
        !          1029:         }
        !          1030:         else {
        !          1031:           struct sk_buff *skb1 = p->recv_skb[p->rmdnum];
        !          1032:           skb_put(skb,R_BUF_SIZE);
        !          1033:           p->recv_skb[p->rmdnum] = skb;
        !          1034:           rmdp->u.buffer = (u32) virt_to_bus(skb->data);
        !          1035:           skb = skb1;
        !          1036:           skb_trim(skb,len);
        !          1037:         }
        !          1038: #else
        !          1039:         skb_put(skb,len);
        !          1040:         eth_copy_and_sum(skb, (unsigned char *) p->recvbounce[p->rmdnum],len,0);
        !          1041: #endif
        !          1042:         p->stats.rx_packets++;
        !          1043:         skb->protocol=eth_type_trans(skb,dev);
        !          1044:         netif_rx(skb);
        !          1045:       }
        !          1046:       else
        !          1047:       {
        !          1048:         printk(KERN_ERR "%s: can't alloc new sk_buff\n",dev->name);
        !          1049:         p->stats.rx_dropped++;
        !          1050:       }
        !          1051:     }
        !          1052:     else {
        !          1053:       printk(KERN_INFO "%s: received runt packet\n",dev->name);
        !          1054:       p->stats.rx_errors++;
        !          1055:     }
        !          1056:     rmdp->blen = -(R_BUF_SIZE-8);
        !          1057:     rmdp->mlen = 0;
        !          1058:     rmdp->u.s.status = RCV_OWN; /* change owner */
        !          1059:     p->rmdnum = (p->rmdnum + 1) & (RMDNUM-1);
        !          1060:     rmdp = p->rmdhead + p->rmdnum;
        !          1061:   }
        !          1062: }
        !          1063: 
        !          1064: /*
        !          1065:  * kick xmitter ..
        !          1066:  */
        !          1067: static int ni65_send_packet(struct sk_buff *skb, struct device *dev)
        !          1068: {
        !          1069:   struct priv *p = (struct priv *) dev->priv;
        !          1070: 
        !          1071:   if(dev->tbusy)
        !          1072:   {
        !          1073:     int tickssofar = jiffies - dev->trans_start;
        !          1074:     if (tickssofar < 50)
        !          1075:       return 1;
        !          1076: 
        !          1077:     printk(KERN_ERR "%s: xmitter timed out, try to restart!\n",dev->name);
        !          1078: {
        !          1079:   int i;
        !          1080:   for(i=0;i<TMDNUM;i++)
        !          1081:     printk("%02x ",p->tmdhead[i].u.s.status);
        !          1082:   printk("\n");
        !          1083: }
        !          1084:     ni65_lance_reinit(dev);
        !          1085:     dev->tbusy=0;
        !          1086:     dev->trans_start = jiffies;
        !          1087:   }
        !          1088: 
        !          1089:   if(skb == NULL) {
        !          1090:     dev_tint(dev);
        !          1091:     return 0;
        !          1092:   }
        !          1093: 
        !          1094:   if (skb->len <= 0)
        !          1095:     return 0;
        !          1096: 
        !          1097:   if (set_bit(0, (void*)&dev->tbusy) != 0) {
        !          1098:      printk(KERN_ERR "%s: Transmitter access conflict.\n", dev->name);
        !          1099:      return 1;
        !          1100:   }
        !          1101:   if (set_bit(0, (void*)&p->lock)) {
        !          1102:        printk(KERN_ERR "%s: Queue was locked.\n", dev->name);
        !          1103:        return 1;
        !          1104:   }
        !          1105: 
        !          1106:   {
        !          1107:     short len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
        !          1108:     struct tmd *tmdp;
        !          1109:     long flags;
        !          1110: 
        !          1111: #ifdef XMT_VIA_SKB
        !          1112:     if( (unsigned long) (skb->data + skb->len) > 0x1000000) {
        !          1113: #endif
        !          1114: 
        !          1115:       memcpy((char *) p->tmdbounce[p->tmdbouncenum] ,(char *)skb->data,
        !          1116:                (skb->len > T_BUF_SIZE) ? T_BUF_SIZE : skb->len);
        !          1117:       dev_kfree_skb (skb, FREE_WRITE);
        !          1118: 
        !          1119:       save_flags(flags);
        !          1120:       cli();
        !          1121: 
        !          1122:       tmdp = p->tmdhead + p->tmdnum;
        !          1123:       tmdp->u.buffer = (u32) virt_to_bus(p->tmdbounce[p->tmdbouncenum]);
        !          1124:       p->tmdbouncenum = (p->tmdbouncenum + 1) & (TMDNUM - 1);
        !          1125: 
        !          1126: #ifdef XMT_VIA_SKB
        !          1127:     }
        !          1128:     else {
        !          1129:       save_flags(flags);
        !          1130:       cli();
        !          1131:  
        !          1132:       tmdp = p->tmdhead + p->tmdnum;
        !          1133:       tmdp->u.buffer = (u32) virt_to_bus(skb->data);
        !          1134:       p->tmd_skb[p->tmdnum] = skb;
        !          1135:     }
        !          1136: #endif
        !          1137:     tmdp->blen = -len;
        !          1138: 
        !          1139:     tmdp->u.s.status = XMIT_OWN | XMIT_START | XMIT_END;
        !          1140:     writedatareg(CSR0_TDMD | CSR0_INEA); /* enable xmit & interrupt */
        !          1141: 
        !          1142:     p->xmit_queued = 1;
        !          1143:     p->tmdnum = (p->tmdnum + 1) & (TMDNUM-1);
        !          1144: 
        !          1145:     dev->tbusy = (p->tmdnum == p->tmdlast) ? 1 : 0;
        !          1146:     p->lock = 0;
        !          1147:     dev->trans_start = jiffies;
        !          1148: 
        !          1149:     restore_flags(flags);
        !          1150:   }
        !          1151: 
        !          1152:   return 0;
        !          1153: }
        !          1154: 
        !          1155: static struct enet_statistics *ni65_get_stats(struct device *dev)
        !          1156: {
        !          1157: 
        !          1158: #if 0
        !          1159:  int i;
        !          1160:  struct priv *p = (struct priv *) dev->priv;
        !          1161:  for(i=0;i<RMDNUM;i++) {
        !          1162:    struct rmd *rmdp = p->rmdhead + ((p->rmdnum + i) & (RMDNUM-1));
        !          1163:    printk("%02x ",rmdp->u.s.status);
        !          1164:  }
        !          1165:  printk("\n");
        !          1166: #endif
        !          1167: 
        !          1168:   return &((struct priv *) dev->priv)->stats;
        !          1169: }
        !          1170: 
        !          1171: static void set_multicast_list(struct device *dev)
        !          1172: {
        !          1173:        if(!ni65_lance_reinit(dev))
        !          1174:                printk(KERN_ERR "%s: Can't switch card into MC mode!\n",dev->name);
        !          1175:        dev->tbusy = 0;
        !          1176: }
        !          1177: 
        !          1178: #ifdef MODULE
        !          1179: static struct device dev_ni65 = {
        !          1180:   "        ",  /* "ni6510": device name inserted by net_init.c */
        !          1181:   0, 0, 0, 0,
        !          1182:   0x360, 9,   /* I/O address, IRQ */
        !          1183:   0, 0, 0, NULL, ni65_probe };
        !          1184: 
        !          1185: /* set: io,irq,dma or set it when calling insmod */
        !          1186: static int irq=0;
        !          1187: static int io=0;
        !          1188: static int dma=0;
        !          1189: 
        !          1190: int init_module(void)
        !          1191: {
        !          1192: #if 0
        !          1193:   if(io <= 0x0 || irq < 2) {
        !          1194:     printk("ni65: Autoprobing not allowed for modules.\n");
        !          1195:     printk("ni65: Set symbols 'io' 'irq' and 'dma'\n");
        !          1196:     return -ENODEV;
        !          1197:   }
        !          1198: #endif
        !          1199:   dev_ni65.irq = irq;
        !          1200:   dev_ni65.dma = dma;
        !          1201:   dev_ni65.base_addr = io;
        !          1202:   if (register_netdev(&dev_ni65) != 0)
        !          1203:     return -EIO;
        !          1204:   return 0;
        !          1205: }
        !          1206: 
        !          1207: void cleanup_module(void)
        !          1208: {
        !          1209:   struct priv *p;
        !          1210:   p = (struct priv *) dev_ni65.priv;
        !          1211:   if(!p) {
        !          1212:     printk("Ooops .. no privat struct\n");
        !          1213:     return;
        !          1214:   }
        !          1215:   disable_dma(dev_ni65.dma);
        !          1216:   free_dma(dev_ni65.dma);
        !          1217:   release_region(dev_ni65.base_addr,cards[p->cardno].total_size);
        !          1218:   ni65_free_buffer(p);
        !          1219:   dev_ni65.priv = NULL;
        !          1220:   unregister_netdev(&dev_ni65);
        !          1221: }
        !          1222: #endif /* MODULE */
        !          1223: 
        !          1224: /*
        !          1225:  * END of ni65.c 
        !          1226:  */
        !          1227: 
        !          1228: 

unix.superglobalmegacorp.com

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