|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.