|
|
1.1 ! root 1: /* ! 2: * Linux ethernet device driver for the 3Com Etherlink Plus (3C505) ! 3: * By Craig Southeren and Juha Laiho ! 4: * ! 5: * 3c505.c This module implements an interface to the 3Com ! 6: * Etherlink Plus (3c505) ethernet card. Linux device ! 7: * driver interface reverse engineered from the Linux 3C509 ! 8: * device drivers. Some 3C505 information gleaned from ! 9: * the Crynwr packet driver. Still this driver would not ! 10: * be here without 3C505 technical reference provided by ! 11: * 3Com. ! 12: * ! 13: * Version: @(#)3c505.c 0.8.4 17-Dec-95 ! 14: * ! 15: * Authors: Linux 3c505 device driver by ! 16: * Craig Southeren, <[email protected]> ! 17: * Final debugging by ! 18: * Andrew Tridgell, <[email protected]> ! 19: * Auto irq/address, tuning, cleanup and v1.1.4+ kernel mods by ! 20: * Juha Laiho, <[email protected]> ! 21: * Linux 3C509 driver by ! 22: * Donald Becker, <[email protected]> ! 23: * Crynwr packet driver by ! 24: * Krishnan Gopalan and Gregg Stefancik, ! 25: * Clemson University Engineering Computer Operations. ! 26: * Portions of the code have been adapted from the 3c505 ! 27: * driver for NCSA Telnet by Bruce Orchard and later ! 28: * modified by Warren Van Houten and [email protected]. ! 29: * 3C505 technical information provided by ! 30: * Terry Murphy, of 3Com Network Adapter Division ! 31: * Linux 1.3.0 changes by ! 32: * Alan Cox <[email protected]> ! 33: * ! 34: */ ! 35: ! 36: #include <linux/module.h> ! 37: ! 38: #include <linux/kernel.h> ! 39: #include <linux/sched.h> ! 40: #include <linux/string.h> ! 41: #include <linux/interrupt.h> ! 42: #include <linux/ptrace.h> ! 43: #include <linux/errno.h> ! 44: #include <linux/in.h> ! 45: #include <linux/malloc.h> ! 46: #include <linux/ioport.h> ! 47: #include <asm/bitops.h> ! 48: #include <asm/io.h> ! 49: ! 50: #include <linux/netdevice.h> ! 51: #include <linux/etherdevice.h> ! 52: #include <linux/skbuff.h> ! 53: ! 54: #include "3c505.h" ! 55: ! 56: /********************************************************* ! 57: * ! 58: * define debug messages here as common strings to reduce space ! 59: * ! 60: *********************************************************/ ! 61: ! 62: static const char * filename = __FILE__; ! 63: ! 64: static const char * null_msg = "*** NULL at %s:%s (line %d) ***\n"; ! 65: #define CHECK_NULL(p) \ ! 66: if (!p) printk(null_msg, filename,__FUNCTION__,__LINE__) ! 67: ! 68: static const char * timeout_msg = "*** timeout at %s:%s (line %d) ***\n"; ! 69: #define TIMEOUT_MSG(lineno) \ ! 70: printk(timeout_msg, filename,__FUNCTION__,(lineno)) ! 71: ! 72: static const char * invalid_pcb_msg = ! 73: "*** invalid pcb length %d at %s:%s (line %d) ***\n"; ! 74: #define INVALID_PCB_MSG(len) \ ! 75: printk(invalid_pcb_msg, (len),filename,__FUNCTION__,__LINE__) ! 76: ! 77: static const char * search_msg = "%s: Looking for 3c505 adapter at address %#x..."; ! 78: ! 79: static const char * stilllooking_msg = "still looking..."; ! 80: ! 81: static const char * found_msg = "found.\n"; ! 82: ! 83: static const char * notfound_msg = "not found (reason = %d)\n"; ! 84: ! 85: static const char * couldnot_msg = "%s: 3c505 not found\n"; ! 86: ! 87: /********************************************************* ! 88: * ! 89: * various other debug stuff ! 90: * ! 91: *********************************************************/ ! 92: ! 93: #ifdef ELP_DEBUG ! 94: static int elp_debug = ELP_DEBUG; ! 95: #else ! 96: static int elp_debug = 0; ! 97: #endif ! 98: ! 99: /* ! 100: * 0 = no messages (well, some) ! 101: * 1 = messages when high level commands performed ! 102: * 2 = messages when low level commands performed ! 103: * 3 = messages when interrupts received ! 104: */ ! 105: ! 106: #define ELP_VERSION "0.8.4" ! 107: ! 108: #ifdef MACH ! 109: #define ELP_NEED_HARD_RESET 0 ! 110: #endif ! 111: ! 112: /***************************************************************** ! 113: * ! 114: * useful macros ! 115: * ! 116: *****************************************************************/ ! 117: ! 118: #ifndef TRUE ! 119: #define TRUE 1 ! 120: #endif ! 121: ! 122: #ifndef FALSE ! 123: #define FALSE 0 ! 124: #endif ! 125: ! 126: ! 127: /***************************************************************** ! 128: * ! 129: * List of I/O-addresses we try to auto-sense ! 130: * Last element MUST BE 0! ! 131: *****************************************************************/ ! 132: ! 133: const int addr_list[]={0x300,0x280,0x310,0}; ! 134: ! 135: /***************************************************************** ! 136: * ! 137: * Functions for I/O (note the inline !) ! 138: * ! 139: *****************************************************************/ ! 140: ! 141: static inline unsigned char ! 142: inb_status (unsigned int base_addr) ! 143: { ! 144: return inb(base_addr+PORT_STATUS); ! 145: } ! 146: ! 147: static inline unsigned char ! 148: inb_control (unsigned int base_addr) ! 149: { ! 150: return inb(base_addr+PORT_CONTROL); ! 151: } ! 152: ! 153: static inline int ! 154: inb_command (unsigned int base_addr) ! 155: { ! 156: return inb(base_addr+PORT_COMMAND); ! 157: } ! 158: ! 159: static inline void ! 160: outb_control (unsigned char val, unsigned int base_addr) ! 161: { ! 162: outb(val, base_addr+PORT_CONTROL); ! 163: } ! 164: ! 165: static inline void ! 166: outb_command (unsigned char val, unsigned int base_addr) ! 167: { ! 168: outb(val, base_addr+PORT_COMMAND); ! 169: } ! 170: ! 171: static inline unsigned int ! 172: inw_data (unsigned int base_addr) ! 173: { ! 174: return inw(base_addr+PORT_DATA); ! 175: } ! 176: ! 177: static inline void ! 178: outw_data (unsigned int val, unsigned int base_addr) ! 179: { ! 180: outw(val, base_addr+PORT_DATA); ! 181: } ! 182: ! 183: ! 184: /***************************************************************** ! 185: * ! 186: * structure to hold context information for adapter ! 187: * ! 188: *****************************************************************/ ! 189: ! 190: typedef struct { ! 191: volatile short got[NUM_TRANSMIT_CMDS]; /* flags for command completion */ ! 192: pcb_struct tx_pcb; /* PCB for foreground sending */ ! 193: pcb_struct rx_pcb; /* PCB for foreground receiving */ ! 194: pcb_struct itx_pcb; /* PCB for background sending */ ! 195: pcb_struct irx_pcb; /* PCB for background receiving */ ! 196: struct enet_statistics stats; ! 197: } elp_device; ! 198: ! 199: static int reset_count=0; ! 200: ! 201: /***************************************************************** ! 202: * ! 203: * useful functions for accessing the adapter ! 204: * ! 205: *****************************************************************/ ! 206: ! 207: /* ! 208: * use this routine when accessing the ASF bits as they are ! 209: * changed asynchronously by the adapter ! 210: */ ! 211: ! 212: /* get adapter PCB status */ ! 213: #define GET_ASF(addr) \ ! 214: (get_status(addr)&ASF_PCB_MASK) ! 215: ! 216: static inline int ! 217: get_status (unsigned int base_addr) ! 218: { ! 219: int timeout = jiffies + 10; ! 220: register int stat1; ! 221: do { ! 222: stat1 = inb_status(base_addr); ! 223: } while (stat1 != inb_status(base_addr) && jiffies < timeout); ! 224: if (jiffies >= timeout) ! 225: TIMEOUT_MSG(__LINE__); ! 226: return stat1; ! 227: } ! 228: ! 229: static inline void ! 230: set_hsf (unsigned int base_addr, int hsf) ! 231: { ! 232: cli(); ! 233: outb_control((inb_control(base_addr)&~HSF_PCB_MASK)|hsf, base_addr); ! 234: sti(); ! 235: } ! 236: ! 237: #define WAIT_HCRE(addr,toval) wait_hcre((addr),(toval),__LINE__) ! 238: static inline int ! 239: wait_hcre (unsigned int base_addr, int toval, int lineno) ! 240: { ! 241: int timeout = jiffies + toval; ! 242: while (((inb_status(base_addr)&HCRE)==0) && (jiffies <= timeout)) ! 243: ; ! 244: if (jiffies >= timeout) { ! 245: TIMEOUT_MSG(lineno); ! 246: return FALSE; ! 247: } ! 248: return TRUE; ! 249: } ! 250: ! 251: static inline int ! 252: wait_fast_hcre (unsigned int base_addr, int toval, int lineno) ! 253: { ! 254: int timeout = 0; ! 255: while (((inb_status(base_addr)&HCRE)==0) && (timeout++ < toval)) ! 256: ; ! 257: if (timeout >= toval) { ! 258: sti(); ! 259: TIMEOUT_MSG(lineno); ! 260: return FALSE; ! 261: } ! 262: return TRUE; ! 263: } ! 264: ! 265: static int start_receive (struct device *, pcb_struct *); ! 266: static void adapter_hard_reset (struct device *); ! 267: ! 268: inline static void ! 269: adapter_reset (struct device * dev) ! 270: { ! 271: int timeout; ! 272: unsigned char orig_hcr=inb_control(dev->base_addr); ! 273: ! 274: elp_device * adapter=dev->priv; ! 275: ! 276: outb_control(0,dev->base_addr); ! 277: ! 278: if (inb_status(dev->base_addr)&ACRF) { ! 279: do { ! 280: inb_command(dev->base_addr); ! 281: timeout=jiffies+2; ! 282: while ((jiffies<=timeout) && !(inb_status(dev->base_addr)&ACRF)) ! 283: ; ! 284: } while (inb_status(dev->base_addr)&ACRF); ! 285: set_hsf(dev->base_addr,HSF_PCB_NAK); ! 286: } ! 287: ! 288: outb_control(inb_control(dev->base_addr)|ATTN|DIR,dev->base_addr); ! 289: timeout=jiffies+1; ! 290: while (jiffies<=timeout) ! 291: ; ! 292: outb_control(inb_control(dev->base_addr)&~ATTN,dev->base_addr); ! 293: timeout=jiffies+1; ! 294: while (jiffies<=timeout) ! 295: ; ! 296: outb_control(inb_control(dev->base_addr)|FLSH,dev->base_addr); ! 297: timeout=jiffies+1; ! 298: while (jiffies<=timeout) ! 299: ; ! 300: outb_control(inb_control(dev->base_addr)&~FLSH,dev->base_addr); ! 301: timeout=jiffies+1; ! 302: while (jiffies<=timeout) ! 303: ; ! 304: ! 305: outb_control(orig_hcr, dev->base_addr); ! 306: if (!start_receive(dev, &adapter->tx_pcb)) ! 307: printk("%s: start receive command failed \n", dev->name); ! 308: } ! 309: ! 310: /***************************************************************** ! 311: * ! 312: * send_pcb ! 313: * Send a PCB to the adapter. ! 314: * ! 315: * output byte to command reg --<--+ ! 316: * wait until HCRE is non zero | ! 317: * loop until all bytes sent -->--+ ! 318: * set HSF1 and HSF2 to 1 ! 319: * output pcb length ! 320: * wait until ASF give ACK or NAK ! 321: * set HSF1 and HSF2 to 0 ! 322: * ! 323: *****************************************************************/ ! 324: ! 325: static int ! 326: send_pcb (struct device * dev, pcb_struct * pcb) ! 327: { ! 328: int i; ! 329: int timeout; ! 330: int cont; ! 331: ! 332: /* ! 333: * load each byte into the command register and ! 334: * wait for the HCRE bit to indicate the adapter ! 335: * had read the byte ! 336: */ ! 337: set_hsf(dev->base_addr,0); ! 338: if ((cont = WAIT_HCRE(dev->base_addr,5))) { ! 339: cli(); ! 340: if (pcb->command==CMD_TRANSMIT_PACKET) ! 341: outb_control(inb_control(dev->base_addr)&~DIR,dev->base_addr); ! 342: outb_command(pcb->command, dev->base_addr); ! 343: sti(); ! 344: cont = WAIT_HCRE(dev->base_addr,5); ! 345: } ! 346: ! 347: if (cont) { ! 348: outb_command(pcb->length, dev->base_addr); ! 349: cont = WAIT_HCRE(dev->base_addr,5); ! 350: } ! 351: ! 352: cli(); ! 353: for (i = 0; cont && (i < pcb->length); i++) { ! 354: outb_command(pcb->data.raw[i], dev->base_addr); ! 355: cont = wait_fast_hcre(dev->base_addr,20000,__LINE__); ! 356: } /* if wait_fast_hcre() failed, has already done sti() */ ! 357: ! 358: /* set the host status bits to indicate end of PCB */ ! 359: /* send the total packet length as well */ ! 360: /* wait for the adapter to indicate that it has read the PCB */ ! 361: if (cont) { ! 362: set_hsf(dev->base_addr,HSF_PCB_END); ! 363: outb_command(2+pcb->length, dev->base_addr); ! 364: sti(); ! 365: timeout = jiffies + 7; ! 366: while (jiffies < timeout) { ! 367: i = GET_ASF(dev->base_addr); ! 368: if ((i == ASF_PCB_ACK) || (i == ASF_PCB_NAK)) ! 369: break; ! 370: } ! 371: ! 372: if (i == ASF_PCB_ACK) { ! 373: reset_count=0; ! 374: return TRUE; ! 375: } ! 376: else if (i == ASF_PCB_NAK) { ! 377: printk("%s: PCB send was NAKed\n", dev->name); ! 378: } else { ! 379: printk("%s: timeout after sending PCB\n", dev->name); ! 380: } ! 381: } else { ! 382: sti(); ! 383: printk("%s: timeout in middle of sending PCB\n", dev->name); ! 384: } ! 385: ! 386: adapter_reset(dev); ! 387: return FALSE; ! 388: } ! 389: ! 390: /***************************************************************** ! 391: * ! 392: * receive_pcb ! 393: * Read a PCB to the adapter ! 394: * ! 395: * wait for ACRF to be non-zero ---<---+ ! 396: * input a byte | ! 397: * if ASF1 and ASF2 were not both one | ! 398: * before byte was read, loop --->---+ ! 399: * set HSF1 and HSF2 for ack ! 400: * ! 401: *****************************************************************/ ! 402: ! 403: static int ! 404: receive_pcb (struct device * dev, pcb_struct * pcb) ! 405: { ! 406: int i, j; ! 407: int total_length; ! 408: int stat; ! 409: int timeout; ! 410: ! 411: CHECK_NULL(pcb); ! 412: CHECK_NULL(dev); ! 413: ! 414: set_hsf(dev->base_addr,0); ! 415: ! 416: /* get the command code */ ! 417: timeout = jiffies + 2; ! 418: while (((stat = get_status(dev->base_addr))&ACRF) == 0 && jiffies < timeout) ! 419: ; ! 420: if (jiffies >= timeout) { ! 421: TIMEOUT_MSG(__LINE__); ! 422: return FALSE; ! 423: } ! 424: ! 425: pcb->command = inb_command(dev->base_addr); ! 426: ! 427: /* read the data length */ ! 428: timeout = jiffies + 3; ! 429: while (((stat = get_status(dev->base_addr)) & ACRF) == 0 && jiffies < timeout) ! 430: ; ! 431: if (jiffies >= timeout) { ! 432: TIMEOUT_MSG(__LINE__); ! 433: return FALSE; ! 434: } ! 435: pcb->length = inb_command(dev->base_addr); ! 436: ! 437: if (pcb->length > MAX_PCB_DATA) { ! 438: INVALID_PCB_MSG(pcb->length); ! 439: adapter_reset(dev); ! 440: return FALSE; ! 441: } ! 442: ! 443: /* read the data */ ! 444: cli(); ! 445: i = 0; ! 446: do { ! 447: j = 0; ! 448: while (((stat = get_status(dev->base_addr))&ACRF) == 0 && j++ < 20000) ! 449: ; ! 450: pcb->data.raw[i++] = inb_command(dev->base_addr); ! 451: if (i > MAX_PCB_DATA) ! 452: INVALID_PCB_MSG(i); ! 453: } while ((stat & ASF_PCB_MASK) != ASF_PCB_END && j < 20000); ! 454: sti(); ! 455: if (j >= 20000) { ! 456: TIMEOUT_MSG(__LINE__); ! 457: return FALSE; ! 458: } ! 459: ! 460: /* woops, the last "data" byte was really the length! */ ! 461: total_length = pcb->data.raw[--i]; ! 462: ! 463: /* safety check total length vs data length */ ! 464: if (total_length != (pcb->length + 2)) { ! 465: if (elp_debug >= 2) ! 466: printk("%s: mangled PCB received\n", dev->name); ! 467: set_hsf(dev->base_addr,HSF_PCB_NAK); ! 468: return FALSE; ! 469: } ! 470: ! 471: set_hsf(dev->base_addr,HSF_PCB_ACK); ! 472: reset_count=0; ! 473: return TRUE; ! 474: } ! 475: ! 476: static void ! 477: adapter_hard_reset (struct device * dev) ! 478: { ! 479: int timeout; ! 480: long flags; ! 481: ! 482: CHECK_NULL(dev); ! 483: ! 484: save_flags(flags); ! 485: sti(); ! 486: ! 487: if (elp_debug > 0) ! 488: printk("%s: Resetting the adapter, please wait (approx 20 s)\n", ! 489: dev->name); ! 490: /* ! 491: * take FLSH and ATTN high ! 492: */ ! 493: outb_control(ATTN|FLSH, dev->base_addr); ! 494: ! 495: /* ! 496: * wait for a little bit ! 497: */ ! 498: for (timeout = jiffies + 20; jiffies <= timeout; ) ! 499: ; ! 500: ! 501: /* ! 502: * now take them low ! 503: */ ! 504: outb_control(0, dev->base_addr); ! 505: ! 506: /* ! 507: * wait for a little bit ! 508: */ ! 509: for (timeout = jiffies + 20; jiffies <= timeout; ) ! 510: ; ! 511: ! 512: /* ! 513: * now hang around until the board gets it's act together ! 514: */ ! 515: for (timeout = jiffies + (100 * 15); jiffies <= timeout; ) ! 516: if (GET_ASF(dev->base_addr) != ASF_PCB_END) ! 517: break; ! 518: restore_flags(flags); ! 519: } ! 520: ! 521: /****************************************************** ! 522: * ! 523: * queue a receive command on the adapter so we will get an ! 524: * interrupt when a packet is received. ! 525: * ! 526: ******************************************************/ ! 527: ! 528: static int ! 529: start_receive (struct device * dev, pcb_struct * tx_pcb) ! 530: { ! 531: CHECK_NULL(dev); ! 532: CHECK_NULL(tx_pcb); ! 533: ! 534: if (elp_debug >= 3) ! 535: printk("%s: restarting receiver\n", dev->name); ! 536: tx_pcb->command = CMD_RECEIVE_PACKET; ! 537: tx_pcb->length = sizeof(struct Rcv_pkt); ! 538: tx_pcb->data.rcv_pkt.buf_seg ! 539: = tx_pcb->data.rcv_pkt.buf_ofs = 0; /* Unused */ ! 540: tx_pcb->data.rcv_pkt.buf_len = 1600; ! 541: tx_pcb->data.rcv_pkt.timeout = 0; /* set timeout to zero */ ! 542: return send_pcb(dev, tx_pcb); ! 543: } ! 544: ! 545: /****************************************************** ! 546: * ! 547: * extract a packet from the adapter ! 548: * this routine is only called from within the interrupt ! 549: * service routine, so no cli/sti calls are needed ! 550: * note that the length is always assumed to be even ! 551: * ! 552: ******************************************************/ ! 553: ! 554: static void ! 555: receive_packet (struct device * dev, int len) ! 556: { ! 557: register int i; ! 558: unsigned short * ptr; ! 559: int timeout; ! 560: int rlen; ! 561: struct sk_buff *skb; ! 562: elp_device * adapter; ! 563: ! 564: CHECK_NULL(dev); ! 565: adapter=dev->priv; ! 566: ! 567: if (len <= 0 || ((len & ~1) != len)) ! 568: if (elp_debug >= 3) { ! 569: sti(); ! 570: printk("*** bad packet len %d at %s(%d)\n",len,filename,__LINE__); ! 571: cli(); ! 572: } ! 573: ! 574: rlen = (len+1) & ~1; ! 575: ! 576: skb = dev_alloc_skb(rlen+2); ! 577: ! 578: /* ! 579: * make sure the data register is going the right way ! 580: */ ! 581: ! 582: outb_control(inb_control(dev->base_addr)|DIR, dev->base_addr); ! 583: ! 584: /* ! 585: * if buffer could not be allocated, swallow it ! 586: */ ! 587: if (skb == NULL) { ! 588: for (i = 0; i < (rlen/2); i++) { ! 589: timeout = 0; ! 590: while ((inb_status(dev->base_addr)&HRDY) == 0 && timeout++ < 20000) ! 591: ; ! 592: if (timeout >= 20000) { ! 593: sti(); ! 594: TIMEOUT_MSG(__LINE__); ! 595: break; ! 596: } ! 597: ! 598: inw_data(dev->base_addr); ! 599: } ! 600: adapter->stats.rx_dropped++; ! 601: ! 602: } else { ! 603: skb_reserve(skb,2); /* 16 byte alignment */ ! 604: skb->dev = dev; ! 605: ! 606: /* ! 607: * now read the data from the adapter ! 608: */ ! 609: ptr = (unsigned short *)skb_put(skb,len); ! 610: for (i = 0; i < (rlen/2); i++) { ! 611: timeout = 0; ! 612: while ((inb_status(dev->base_addr)&HRDY) == 0 && timeout++ < 20000) ! 613: ; ! 614: if (timeout >= 20000) { ! 615: sti(); ! 616: printk("*** timeout at %s(%d) reading word %d of %d ***\n", ! 617: filename,__LINE__, i, rlen/2); ! 618: kfree_skb(skb, FREE_WRITE); ! 619: return; ! 620: } ! 621: ! 622: *ptr = inw_data(dev->base_addr); ! 623: ptr++; ! 624: } ! 625: ! 626: sti(); ! 627: skb->protocol=eth_type_trans(skb,dev); ! 628: netif_rx(skb); ! 629: } ! 630: ! 631: outb_control(inb_control(dev->base_addr)&~DIR, dev->base_addr); ! 632: } ! 633: ! 634: ! 635: /****************************************************** ! 636: * ! 637: * interrupt handler ! 638: * ! 639: ******************************************************/ ! 640: ! 641: static void ! 642: elp_interrupt (int irq, struct pt_regs *reg_ptr) ! 643: { ! 644: int len; ! 645: int dlen; ! 646: struct device *dev; ! 647: elp_device * adapter; ! 648: int timeout; ! 649: ! 650: if (irq < 0 || irq > 15) { ! 651: printk ("elp_interrupt(): illegal IRQ number found in interrupt routine (%i)\n", irq); ! 652: return; ! 653: } ! 654: ! 655: dev = irq2dev_map[irq]; ! 656: ! 657: if (dev == NULL) { ! 658: printk ("elp_interrupt(): irq %d for unknown device.\n", irq); ! 659: return; ! 660: } ! 661: ! 662: adapter = (elp_device *) dev->priv; ! 663: ! 664: CHECK_NULL(adapter); ! 665: ! 666: if (dev->interrupt) ! 667: if (elp_debug >= 2) ! 668: printk("%s: Re-entering the interrupt handler.\n", dev->name); ! 669: dev->interrupt = 1; ! 670: ! 671: /* ! 672: * allow interrupts (we need timers!) ! 673: */ ! 674: sti(); ! 675: ! 676: /* ! 677: * receive a PCB from the adapter ! 678: */ ! 679: timeout = jiffies + 3; ! 680: while ((inb_status(dev->base_addr)&ACRF) != 0 && jiffies < timeout) { ! 681: ! 682: if (receive_pcb(dev, &adapter->irx_pcb)) { ! 683: ! 684: switch (adapter->irx_pcb.command) { ! 685: ! 686: /* ! 687: * received a packet - this must be handled fast ! 688: */ ! 689: case CMD_RECEIVE_PACKET_COMPLETE: ! 690: /* if the device isn't open, don't pass packets up the stack */ ! 691: if (dev->start == 0) ! 692: break; ! 693: cli(); ! 694: /* Set direction of adapter FIFO */ ! 695: outb_control(inb_control(dev->base_addr)|DIR, ! 696: dev->base_addr); ! 697: len = adapter->irx_pcb.data.rcv_resp.pkt_len; ! 698: dlen = adapter->irx_pcb.data.rcv_resp.buf_len; ! 699: if (adapter->irx_pcb.data.rcv_resp.timeout != 0) { ! 700: printk("%s: interrupt - packet not received correctly\n", dev->name); ! 701: sti(); ! 702: } else { ! 703: if (elp_debug >= 3) { ! 704: sti(); ! 705: printk("%s: interrupt - packet received of length %i (%i)\n", dev->name, len, dlen); ! 706: cli(); ! 707: } ! 708: receive_packet(dev, dlen); ! 709: sti(); ! 710: if (elp_debug >= 3) ! 711: printk("%s: packet received\n", dev->name); ! 712: } ! 713: if (dev->start && !start_receive(dev, &adapter->itx_pcb)) ! 714: if (elp_debug >= 2) ! 715: printk("%s: interrupt - failed to send receive start PCB\n", dev->name); ! 716: if (elp_debug >= 3) ! 717: printk("%s: receive procedure complete\n", dev->name); ! 718: ! 719: break; ! 720: ! 721: /* ! 722: * 82586 configured correctly ! 723: */ ! 724: case CMD_CONFIGURE_82586_RESPONSE: ! 725: adapter->got[CMD_CONFIGURE_82586] = 1; ! 726: if (elp_debug >= 3) ! 727: printk("%s: interrupt - configure response received\n", dev->name); ! 728: break; ! 729: ! 730: /* ! 731: * Adapter memory configuration ! 732: */ ! 733: case CMD_CONFIGURE_ADAPTER_RESPONSE: ! 734: adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] = 1; ! 735: if (elp_debug >= 3) ! 736: printk("%s: Adapter memory configuration %s.\n",dev->name, ! 737: adapter->irx_pcb.data.failed?"failed":"succeeded"); ! 738: break; ! 739: ! 740: /* ! 741: * Multicast list loading ! 742: */ ! 743: case CMD_LOAD_MULTICAST_RESPONSE: ! 744: adapter->got[CMD_LOAD_MULTICAST_LIST] = 1; ! 745: if (elp_debug >= 3) ! 746: printk("%s: Multicast address list loading %s.\n",dev->name, ! 747: adapter->irx_pcb.data.failed?"failed":"succeeded"); ! 748: break; ! 749: ! 750: /* ! 751: * Station address setting ! 752: */ ! 753: case CMD_SET_ADDRESS_RESPONSE: ! 754: adapter->got[CMD_SET_STATION_ADDRESS] = 1; ! 755: if (elp_debug >= 3) ! 756: printk("%s: Ethernet address setting %s.\n",dev->name, ! 757: adapter->irx_pcb.data.failed?"failed":"succeeded"); ! 758: break; ! 759: ! 760: ! 761: /* ! 762: * received board statistics ! 763: */ ! 764: case CMD_NETWORK_STATISTICS_RESPONSE: ! 765: adapter->stats.rx_packets += adapter->irx_pcb.data.netstat.tot_recv; ! 766: adapter->stats.tx_packets += adapter->irx_pcb.data.netstat.tot_xmit; ! 767: adapter->stats.rx_crc_errors += adapter->irx_pcb.data.netstat.err_CRC; ! 768: adapter->stats.rx_frame_errors += adapter->irx_pcb.data.netstat.err_align; ! 769: adapter->stats.rx_fifo_errors += adapter->irx_pcb.data.netstat.err_ovrrun; ! 770: adapter->got[CMD_NETWORK_STATISTICS] = 1; ! 771: if (elp_debug >= 3) ! 772: printk("%s: interrupt - statistics response received\n", dev->name); ! 773: break; ! 774: ! 775: /* ! 776: * sent a packet ! 777: */ ! 778: case CMD_TRANSMIT_PACKET_COMPLETE: ! 779: if (elp_debug >= 3) ! 780: printk("%s: interrupt - packet sent\n", dev->name); ! 781: if (dev->start == 0) ! 782: break; ! 783: if (adapter->irx_pcb.data.xmit_resp.c_stat != 0) ! 784: if (elp_debug >= 2) ! 785: printk("%s: interrupt - error sending packet %4.4x\n", ! 786: dev->name, adapter->irx_pcb.data.xmit_resp.c_stat); ! 787: dev->tbusy = 0; ! 788: mark_bh(NET_BH); ! 789: break; ! 790: ! 791: /* ! 792: * some unknown PCB ! 793: */ ! 794: default: ! 795: printk("%s: unknown PCB received - %2.2x\n", dev->name, adapter->irx_pcb.command); ! 796: break; ! 797: } ! 798: } else { ! 799: printk("%s: failed to read PCB on interrupt\n", dev->name); ! 800: adapter_reset(dev); ! 801: } ! 802: } ! 803: ! 804: /* ! 805: * indicate no longer in interrupt routine ! 806: */ ! 807: dev->interrupt = 0; ! 808: } ! 809: ! 810: ! 811: /****************************************************** ! 812: * ! 813: * open the board ! 814: * ! 815: ******************************************************/ ! 816: ! 817: static int ! 818: elp_open (struct device *dev) ! 819: { ! 820: elp_device * adapter; ! 821: ! 822: CHECK_NULL(dev); ! 823: ! 824: adapter = dev->priv; ! 825: ! 826: if (elp_debug >= 3) ! 827: printk("%s: request to open device\n", dev->name); ! 828: ! 829: /* ! 830: * make sure we actually found the device ! 831: */ ! 832: if (adapter == NULL) { ! 833: printk("%s: Opening a non-existent physical device\n", dev->name); ! 834: return -EAGAIN; ! 835: } ! 836: ! 837: /* ! 838: * disable interrupts on the board ! 839: */ ! 840: outb_control(0x00, dev->base_addr); ! 841: ! 842: /* ! 843: * clear any pending interrupts ! 844: */ ! 845: inb_command(dev->base_addr); ! 846: adapter_reset(dev); ! 847: ! 848: /* ! 849: * interrupt routine not entered ! 850: */ ! 851: dev->interrupt = 0; ! 852: ! 853: /* ! 854: * transmitter not busy ! 855: */ ! 856: dev->tbusy = 0; ! 857: ! 858: /* ! 859: * make sure we can find the device header given the interrupt number ! 860: */ ! 861: irq2dev_map[dev->irq] = dev; ! 862: ! 863: /* ! 864: * install our interrupt service routine ! 865: */ ! 866: if (request_irq(dev->irq, &elp_interrupt, 0, "3c505")) { ! 867: irq2dev_map[dev->irq] = NULL; ! 868: return -EAGAIN; ! 869: } ! 870: ! 871: /* ! 872: * enable interrupts on the board ! 873: */ ! 874: outb_control(CMDE, dev->base_addr); ! 875: ! 876: /* ! 877: * device is now officially open! ! 878: */ ! 879: dev->start = 1; ! 880: ! 881: /* ! 882: * configure adapter memory: we need 10 multicast addresses, default==0 ! 883: */ ! 884: if (elp_debug >= 3) ! 885: printk("%s: sending 3c505 memory configuration command\n", dev->name); ! 886: adapter->tx_pcb.command = CMD_CONFIGURE_ADAPTER_MEMORY; ! 887: adapter->tx_pcb.data.memconf.cmd_q = 10; ! 888: adapter->tx_pcb.data.memconf.rcv_q = 20; ! 889: adapter->tx_pcb.data.memconf.mcast = 10; ! 890: adapter->tx_pcb.data.memconf.frame = 20; ! 891: adapter->tx_pcb.data.memconf.rcv_b = 20; ! 892: adapter->tx_pcb.data.memconf.progs = 0; ! 893: adapter->tx_pcb.length = sizeof(struct Memconf); ! 894: adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] = 0; ! 895: if (!send_pcb(dev, &adapter->tx_pcb)) ! 896: printk("%s: couldn't send memory configuration command\n", dev->name); ! 897: else { ! 898: int timeout = jiffies + TIMEOUT; ! 899: while (adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] == 0 && jiffies < timeout) ! 900: ; ! 901: if (jiffies >= timeout) ! 902: TIMEOUT_MSG(__LINE__); ! 903: } ! 904: ! 905: ! 906: /* ! 907: * configure adapter to receive broadcast messages and wait for response ! 908: */ ! 909: if (elp_debug >= 3) ! 910: printk("%s: sending 82586 configure command\n", dev->name); ! 911: adapter->tx_pcb.command = CMD_CONFIGURE_82586; ! 912: adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD; ! 913: adapter->tx_pcb.length = 2; ! 914: adapter->got[CMD_CONFIGURE_82586] = 0; ! 915: if (!send_pcb(dev, &adapter->tx_pcb)) ! 916: printk("%s: couldn't send 82586 configure command\n", dev->name); ! 917: else { ! 918: int timeout = jiffies + TIMEOUT; ! 919: while (adapter->got[CMD_CONFIGURE_82586] == 0 && jiffies < timeout) ! 920: ; ! 921: if (jiffies >= timeout) ! 922: TIMEOUT_MSG(__LINE__); ! 923: } ! 924: ! 925: /* ! 926: * queue receive commands to provide buffering ! 927: */ ! 928: if (!start_receive(dev, &adapter->tx_pcb)) ! 929: printk("%s: start receive command failed \n", dev->name); ! 930: if (elp_debug >= 3) ! 931: printk("%s: start receive command sent\n", dev->name); ! 932: ! 933: MOD_INC_USE_COUNT; ! 934: ! 935: return 0; /* Always succeed */ ! 936: } ! 937: ! 938: ! 939: /****************************************************** ! 940: * ! 941: * send a packet to the adapter ! 942: * ! 943: ******************************************************/ ! 944: ! 945: static int ! 946: send_packet (struct device * dev, unsigned char * ptr, int len) ! 947: { ! 948: int i; ! 949: int timeout = 0; ! 950: elp_device * adapter; ! 951: ! 952: /* ! 953: * make sure the length is even and no shorter than 60 bytes ! 954: */ ! 955: unsigned int nlen = (((len < 60) ? 60 : len) + 1) & (~1); ! 956: ! 957: CHECK_NULL(dev); ! 958: CHECK_NULL(ptr); ! 959: ! 960: adapter = dev->priv; ! 961: ! 962: if (nlen < len) ! 963: printk("Warning, bad length nlen=%d len=%d %s(%d)\n",nlen,len,filename,__LINE__); ! 964: ! 965: /* ! 966: * send the adapter a transmit packet command. Ignore segment and offset ! 967: * and make sure the length is even ! 968: */ ! 969: adapter->tx_pcb.command = CMD_TRANSMIT_PACKET; ! 970: adapter->tx_pcb.length = sizeof(struct Xmit_pkt); ! 971: adapter->tx_pcb.data.xmit_pkt.buf_ofs ! 972: = adapter->tx_pcb.data.xmit_pkt.buf_seg = 0; /* Unused */ ! 973: adapter->tx_pcb.data.xmit_pkt.pkt_len = nlen; ! 974: if (!send_pcb(dev, &adapter->tx_pcb)) { ! 975: return FALSE; ! 976: } ! 977: ! 978: /* ! 979: * write data to the adapter ! 980: */ ! 981: cli(); ! 982: for (i = 0; i < (nlen/2);i++) { ! 983: while (((inb_status(dev->base_addr)&HRDY) == 0) ! 984: && (timeout++ < 20000)) ! 985: ; ! 986: if (timeout >= 20000) { ! 987: sti(); ! 988: printk("%s: timeout at %s(%d) writing word %d of %d ***\n", ! 989: dev->name,filename,__LINE__, i, nlen/2); ! 990: return FALSE; ! 991: } ! 992: ! 993: outw_data(*(short *)ptr, dev->base_addr); ! 994: ptr +=2; ! 995: } ! 996: sti(); ! 997: ! 998: return TRUE; ! 999: } ! 1000: ! 1001: /****************************************************** ! 1002: * ! 1003: * start the transmitter ! 1004: * return 0 if sent OK, else return 1 ! 1005: * ! 1006: ******************************************************/ ! 1007: ! 1008: static int ! 1009: elp_start_xmit (struct sk_buff *skb, struct device *dev) ! 1010: { ! 1011: CHECK_NULL(dev); ! 1012: ! 1013: /* ! 1014: * not sure what this does, but the 3c509 driver does it, so... ! 1015: */ ! 1016: if (skb == NULL) { ! 1017: dev_tint(dev); ! 1018: return 0; ! 1019: } ! 1020: ! 1021: /* ! 1022: * if we ended up with a munged length, don't send it ! 1023: */ ! 1024: if (skb->len <= 0) ! 1025: return 0; ! 1026: ! 1027: if (elp_debug >= 3) ! 1028: printk("%s: request to send packet of length %d\n", dev->name, (int)skb->len); ! 1029: ! 1030: /* ! 1031: * if the transmitter is still busy, we have a transmit timeout... ! 1032: */ ! 1033: if (dev->tbusy) { ! 1034: int tickssofar = jiffies - dev->trans_start; ! 1035: int stat; ! 1036: if (tickssofar < 50) /* was 500, AJT */ ! 1037: return 1; ! 1038: printk("%s: transmit timed out, not resetting adapter\n", dev->name); ! 1039: if (((stat=inb_status(dev->base_addr))&ACRF) != 0) ! 1040: printk("%s: hmmm...seemed to have missed an interrupt!\n", dev->name); ! 1041: printk("%s: status %#02x\n", dev->name, stat); ! 1042: dev->trans_start = jiffies; ! 1043: dev->tbusy = 0; ! 1044: } ! 1045: ! 1046: /* ! 1047: * send the packet at skb->data for skb->len ! 1048: */ ! 1049: if (!send_packet(dev, skb->data, skb->len)) { ! 1050: printk("%s: send packet PCB failed\n", dev->name); ! 1051: return 1; ! 1052: } ! 1053: ! 1054: if (elp_debug >= 3) ! 1055: printk("%s: packet of length %d sent\n", dev->name, (int)skb->len); ! 1056: ! 1057: ! 1058: /* ! 1059: * start the transmit timeout ! 1060: */ ! 1061: dev->trans_start = jiffies; ! 1062: ! 1063: /* ! 1064: * the transmitter is now busy ! 1065: */ ! 1066: dev->tbusy = 1; ! 1067: ! 1068: /* ! 1069: * free the buffer ! 1070: */ ! 1071: dev_kfree_skb(skb, FREE_WRITE); ! 1072: ! 1073: return 0; ! 1074: } ! 1075: ! 1076: /****************************************************** ! 1077: * ! 1078: * return statistics on the board ! 1079: * ! 1080: ******************************************************/ ! 1081: ! 1082: static struct enet_statistics * ! 1083: elp_get_stats (struct device *dev) ! 1084: { ! 1085: elp_device *adapter = (elp_device *) dev->priv; ! 1086: ! 1087: if (elp_debug >= 3) ! 1088: printk("%s: request for stats\n", dev->name); ! 1089: ! 1090: /* If the device is closed, just return the latest stats we have, ! 1091: - we cannot ask from the adapter without interrupts */ ! 1092: if (!dev->start) ! 1093: return &adapter->stats; ! 1094: ! 1095: /* send a get statistics command to the board */ ! 1096: adapter->tx_pcb.command = CMD_NETWORK_STATISTICS; ! 1097: adapter->tx_pcb.length = 0; ! 1098: adapter->got[CMD_NETWORK_STATISTICS] = 0; ! 1099: if (!send_pcb(dev, &adapter->tx_pcb)) ! 1100: printk("%s: couldn't send get statistics command\n", dev->name); ! 1101: else { ! 1102: int timeout = jiffies + TIMEOUT; ! 1103: while (adapter->got[CMD_NETWORK_STATISTICS] == 0 && jiffies < timeout) ! 1104: ; ! 1105: if (jiffies >= timeout) { ! 1106: TIMEOUT_MSG(__LINE__); ! 1107: return &adapter->stats; ! 1108: } ! 1109: } ! 1110: ! 1111: /* statistics are now up to date */ ! 1112: return &adapter->stats; ! 1113: } ! 1114: ! 1115: /****************************************************** ! 1116: * ! 1117: * close the board ! 1118: * ! 1119: ******************************************************/ ! 1120: ! 1121: static int ! 1122: elp_close (struct device *dev) ! 1123: { ! 1124: elp_device * adapter; ! 1125: ! 1126: CHECK_NULL(dev); ! 1127: adapter = dev->priv; ! 1128: CHECK_NULL(adapter); ! 1129: ! 1130: if (elp_debug >= 3) ! 1131: printk("%s: request to close device\n", dev->name); ! 1132: ! 1133: /* Someone may request the device statistic information even when ! 1134: * the interface is closed. The following will update the statistics ! 1135: * structure in the driver, so we'll be able to give current statistics. ! 1136: */ ! 1137: (void) elp_get_stats(dev); ! 1138: ! 1139: /* ! 1140: * disable interrupts on the board ! 1141: */ ! 1142: outb_control(0x00, dev->base_addr); ! 1143: ! 1144: /* ! 1145: * flag transmitter as busy (i.e. not available) ! 1146: */ ! 1147: dev->tbusy = 1; ! 1148: ! 1149: /* ! 1150: * indicate device is closed ! 1151: */ ! 1152: dev->start = 0; ! 1153: ! 1154: /* ! 1155: * release the IRQ ! 1156: */ ! 1157: free_irq(dev->irq); ! 1158: ! 1159: /* ! 1160: * and we no longer have to map irq to dev either ! 1161: */ ! 1162: irq2dev_map[dev->irq] = 0; ! 1163: ! 1164: MOD_DEC_USE_COUNT; ! 1165: ! 1166: return 0; ! 1167: } ! 1168: ! 1169: ! 1170: /************************************************************ ! 1171: * ! 1172: * Set multicast list ! 1173: * num_addrs==0: clear mc_list ! 1174: * num_addrs==-1: set promiscuous mode ! 1175: * num_addrs>0: set mc_list ! 1176: * ! 1177: ************************************************************/ ! 1178: ! 1179: static void ! 1180: elp_set_mc_list (struct device *dev) ! 1181: { ! 1182: elp_device *adapter = (elp_device *) dev->priv; ! 1183: struct dev_mc_list *dmi=dev->mc_list; ! 1184: int i; ! 1185: ! 1186: if (elp_debug >= 3) ! 1187: printk("%s: request to set multicast list\n", dev->name); ! 1188: ! 1189: if (!(dev->flags&(IFF_PROMISC|IFF_ALLMULTI))) ! 1190: { ! 1191: /* send a "load multicast list" command to the board, max 10 addrs/cmd */ ! 1192: /* if num_addrs==0 the list will be cleared */ ! 1193: adapter->tx_pcb.command = CMD_LOAD_MULTICAST_LIST; ! 1194: adapter->tx_pcb.length = 6*dev->mc_count; ! 1195: for (i=0;i<dev->mc_count;i++) ! 1196: { ! 1197: memcpy(adapter->tx_pcb.data.multicast[i], dmi->dmi_addr,6); ! 1198: dmi=dmi->next; ! 1199: } ! 1200: adapter->got[CMD_LOAD_MULTICAST_LIST] = 0; ! 1201: if (!send_pcb(dev, &adapter->tx_pcb)) ! 1202: printk("%s: couldn't send set_multicast command\n", dev->name); ! 1203: else { ! 1204: int timeout = jiffies + TIMEOUT; ! 1205: while (adapter->got[CMD_LOAD_MULTICAST_LIST] == 0 && jiffies < timeout) ! 1206: ; ! 1207: if (jiffies >= timeout) { ! 1208: TIMEOUT_MSG(__LINE__); ! 1209: } ! 1210: } ! 1211: if (dev->mc_count) ! 1212: adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD | RECV_MULTI; ! 1213: else /* num_addrs == 0 */ ! 1214: adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD; ! 1215: } ! 1216: else ! 1217: adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_PROMISC; ! 1218: /* ! 1219: * configure adapter to receive messages (as specified above) ! 1220: * and wait for response ! 1221: */ ! 1222: if (elp_debug >= 3) ! 1223: printk("%s: sending 82586 configure command\n", dev->name); ! 1224: adapter->tx_pcb.command = CMD_CONFIGURE_82586; ! 1225: adapter->tx_pcb.length = 2; ! 1226: adapter->got[CMD_CONFIGURE_82586] = 0; ! 1227: if (!send_pcb(dev, &adapter->tx_pcb)) ! 1228: printk("%s: couldn't send 82586 configure command\n", dev->name); ! 1229: else { ! 1230: int timeout = jiffies + TIMEOUT; ! 1231: while (adapter->got[CMD_CONFIGURE_82586] == 0 && jiffies < timeout) ! 1232: ; ! 1233: if (jiffies >= timeout) ! 1234: TIMEOUT_MSG(__LINE__); ! 1235: } ! 1236: } ! 1237: ! 1238: /****************************************************** ! 1239: * ! 1240: * initialise Etherlink Plus board ! 1241: * ! 1242: ******************************************************/ ! 1243: ! 1244: static void ! 1245: elp_init (struct device *dev) ! 1246: { ! 1247: elp_device * adapter; ! 1248: ! 1249: CHECK_NULL(dev); ! 1250: ! 1251: /* ! 1252: * set ptrs to various functions ! 1253: */ ! 1254: dev->open = elp_open; /* local */ ! 1255: dev->stop = elp_close; /* local */ ! 1256: dev->get_stats = elp_get_stats; /* local */ ! 1257: dev->hard_start_xmit = elp_start_xmit; /* local */ ! 1258: dev->set_multicast_list = elp_set_mc_list; /* local */ ! 1259: ! 1260: /* Setup the generic properties */ ! 1261: ether_setup(dev); ! 1262: ! 1263: /* ! 1264: * setup ptr to adapter specific information ! 1265: */ ! 1266: adapter = (elp_device *)(dev->priv = kmalloc(sizeof(elp_device), GFP_KERNEL)); ! 1267: CHECK_NULL(adapter); ! 1268: if (adapter == NULL) ! 1269: return; ! 1270: memset(&(adapter->stats), 0, sizeof(struct enet_statistics)); ! 1271: ! 1272: /* ! 1273: * memory information ! 1274: */ ! 1275: dev->mem_start = dev->mem_end = dev->rmem_end = dev->rmem_start = 0; ! 1276: } ! 1277: ! 1278: /************************************************************ ! 1279: * ! 1280: * A couple of tests to see if there's 3C505 or not ! 1281: * Called only by elp_autodetect ! 1282: ************************************************************/ ! 1283: ! 1284: static int ! 1285: elp_sense (struct device * dev) ! 1286: { ! 1287: int timeout; ! 1288: int addr=dev->base_addr; ! 1289: const char *name=dev->name; ! 1290: long flags; ! 1291: byte orig_HCR, orig_HSR; ! 1292: ! 1293: if (check_region(addr, 0xf)) ! 1294: return -1; ! 1295: ! 1296: orig_HCR=inb_control(addr); ! 1297: orig_HSR=inb_status(addr); ! 1298: ! 1299: if (elp_debug > 0) ! 1300: printk(search_msg, name, addr); ! 1301: ! 1302: if (((orig_HCR==0xff) && (orig_HSR==0xff)) || ! 1303: ((orig_HCR & DIR) != (orig_HSR & DIR))) { ! 1304: if (elp_debug > 0) ! 1305: printk(notfound_msg, 1); ! 1306: return -1; /* It can't be 3c505 if HCR.DIR != HSR.DIR */ ! 1307: } ! 1308: ! 1309: /* Enable interrupts - we need timers! */ ! 1310: save_flags(flags); ! 1311: sti(); ! 1312: ! 1313: /* Wait for a while; the adapter may still be booting up */ ! 1314: if (elp_debug > 0) ! 1315: printk(stilllooking_msg); ! 1316: for (timeout = jiffies + (100 * 15); jiffies <= timeout; ) ! 1317: if (GET_ASF(addr) != ASF_PCB_END) ! 1318: break; ! 1319: ! 1320: if (orig_HCR & DIR) { ! 1321: /* If HCR.DIR is up, we pull it down. HSR.DIR should follow. */ ! 1322: outb_control(orig_HCR & ~DIR,addr); ! 1323: timeout = jiffies+30; ! 1324: while (jiffies < timeout) ! 1325: ; ! 1326: restore_flags(flags); ! 1327: if (inb_status(addr) & DIR) { ! 1328: outb_control(orig_HCR,addr); ! 1329: if (elp_debug > 0) ! 1330: printk(notfound_msg, 2); ! 1331: return -1; ! 1332: } ! 1333: } else { ! 1334: /* If HCR.DIR is down, we pull it up. HSR.DIR should follow. */ ! 1335: outb_control(orig_HCR | DIR,addr); ! 1336: timeout = jiffies+300; ! 1337: while (jiffies < timeout) ! 1338: ; ! 1339: restore_flags(flags); ! 1340: if (!(inb_status(addr) & DIR)) { ! 1341: outb_control(orig_HCR,addr); ! 1342: if (elp_debug > 0) ! 1343: printk(notfound_msg, 3); ! 1344: return -1; ! 1345: } ! 1346: } ! 1347: /* ! 1348: * It certainly looks like a 3c505. If it has DMA enabled, it needs ! 1349: * a hard reset. Also, do a hard reset if selected at the compile time. ! 1350: */ ! 1351: if (elp_debug > 0) ! 1352: printk(found_msg); ! 1353: ! 1354: if (((orig_HCR==0x35) && (orig_HSR==0x5b)) || ELP_NEED_HARD_RESET) ! 1355: adapter_hard_reset(dev); ! 1356: return 0; ! 1357: } ! 1358: ! 1359: /************************************************************* ! 1360: * ! 1361: * Search through addr_list[] and try to find a 3C505 ! 1362: * Called only by eplus_probe ! 1363: *************************************************************/ ! 1364: ! 1365: static int ! 1366: elp_autodetect (struct device * dev) ! 1367: { ! 1368: int idx=0; ! 1369: ! 1370: /* if base address set, then only check that address ! 1371: otherwise, run through the table */ ! 1372: if (dev->base_addr != 0) { /* dev->base_addr == 0 ==> plain autodetect */ ! 1373: if (elp_sense(dev) == 0) ! 1374: return dev->base_addr; ! 1375: } else while ( (dev->base_addr=addr_list[idx++]) ) { ! 1376: if (elp_sense(dev) == 0) ! 1377: return dev->base_addr; ! 1378: } ! 1379: ! 1380: /* could not find an adapter */ ! 1381: if (elp_debug > 0) ! 1382: printk(couldnot_msg, dev->name); ! 1383: ! 1384: return 0; /* Because of this, the layer above will return -ENODEV */ ! 1385: } ! 1386: ! 1387: /****************************************************** ! 1388: * ! 1389: * probe for an Etherlink Plus board at the specified address ! 1390: * ! 1391: ******************************************************/ ! 1392: ! 1393: int ! 1394: elplus_probe (struct device *dev) ! 1395: { ! 1396: elp_device adapter; ! 1397: int i; ! 1398: ! 1399: CHECK_NULL(dev); ! 1400: ! 1401: /* ! 1402: * setup adapter structure ! 1403: */ ! 1404: ! 1405: dev->base_addr = elp_autodetect(dev); ! 1406: if ( !(dev->base_addr) ) ! 1407: return -ENODEV; ! 1408: ! 1409: /* ! 1410: * As we enter here from bootup, the adapter should have IRQs enabled, ! 1411: * but we can as well enable them anyway. ! 1412: */ ! 1413: outb_control(inb_control(dev->base_addr) | CMDE, dev->base_addr); ! 1414: autoirq_setup(0); ! 1415: ! 1416: /* ! 1417: * use ethernet address command to probe for board in polled mode ! 1418: * (this also makes us the IRQ that we need for automatic detection) ! 1419: */ ! 1420: adapter.tx_pcb.command = CMD_STATION_ADDRESS; ! 1421: adapter.tx_pcb.length = 0; ! 1422: if (!send_pcb (dev, &adapter.tx_pcb) || ! 1423: !receive_pcb(dev, &adapter.rx_pcb) || ! 1424: (adapter.rx_pcb.command != CMD_ADDRESS_RESPONSE) || ! 1425: (adapter.rx_pcb.length != 6)) { ! 1426: printk("%s: not responding to first PCB\n", dev->name); ! 1427: return -ENODEV; ! 1428: } ! 1429: ! 1430: if (dev->irq) { /* Is there a preset IRQ? */ ! 1431: if (dev->irq != autoirq_report(0)) { ! 1432: printk("%s: Detected IRQ doesn't match user-defined one.\n",dev->name); ! 1433: return -ENODEV; ! 1434: } ! 1435: /* if dev->irq == autoirq_report(0), all is well */ ! 1436: } else /* No preset IRQ; just use what we can detect */ ! 1437: dev->irq=autoirq_report(0); ! 1438: switch (dev->irq) { /* Legal, sane? */ ! 1439: case 0: ! 1440: printk("%s: No IRQ reported by autoirq_report().\n",dev->name); ! 1441: printk("%s: Check the jumpers of your 3c505 board.\n",dev->name); ! 1442: return -ENODEV; ! 1443: case 1: ! 1444: case 6: ! 1445: case 8: ! 1446: case 13: ! 1447: printk("%s: Impossible IRQ %d reported by autoirq_report().\n", ! 1448: dev->name, dev->irq); ! 1449: return -ENODEV; ! 1450: } ! 1451: /* ! 1452: * Now we have the IRQ number so we can disable the interrupts from ! 1453: * the board until the board is opened. ! 1454: */ ! 1455: outb_control(inb_control(dev->base_addr) & ~CMDE, dev->base_addr); ! 1456: ! 1457: /* ! 1458: * copy ethernet address into structure ! 1459: */ ! 1460: for (i = 0; i < 6; i++) ! 1461: dev->dev_addr[i] = adapter.rx_pcb.data.eth_addr[i]; ! 1462: ! 1463: /* ! 1464: * print remainder of startup message ! 1465: */ ! 1466: printk("%s: 3c505 card found at I/O %#lx using IRQ%d" ! 1467: " has address %02x:%02x:%02x:%02x:%02x:%02x\n", ! 1468: dev->name, dev->base_addr, dev->irq, ! 1469: dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], ! 1470: dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); ! 1471: ! 1472: /* ! 1473: * and reserve the address region ! 1474: */ ! 1475: request_region(dev->base_addr, ELP_IO_EXTENT, "3c505"); ! 1476: ! 1477: /* ! 1478: * initialise the device ! 1479: */ ! 1480: elp_init(dev); ! 1481: return 0; ! 1482: } ! 1483: ! 1484: #ifdef MODULE ! 1485: static char devicename[9] = { 0, }; ! 1486: static struct device dev_3c505 = { ! 1487: devicename, /* device name is inserted by linux/drivers/net/net_init.c */ ! 1488: 0, 0, 0, 0, ! 1489: 0, 0, ! 1490: 0, 0, 0, NULL, elplus_probe }; ! 1491: ! 1492: int io = 0x300; ! 1493: int irq = 0; ! 1494: ! 1495: int init_module(void) ! 1496: { ! 1497: if (io == 0) ! 1498: printk("3c505: You should not use auto-probing with insmod!\n"); ! 1499: dev_3c505.base_addr = io; ! 1500: dev_3c505.irq = irq; ! 1501: if (register_netdev(&dev_3c505) != 0) { ! 1502: printk("3c505: register_netdev() returned non-zero.\n"); ! 1503: return -EIO; ! 1504: } ! 1505: return 0; ! 1506: } ! 1507: ! 1508: void ! 1509: cleanup_module(void) ! 1510: { ! 1511: unregister_netdev(&dev_3c505); ! 1512: kfree(dev_3c505.priv); ! 1513: dev_3c505.priv = NULL; ! 1514: ! 1515: /* If we don't do this, we can't re-insmod it later. */ ! 1516: release_region(dev_3c505.base_addr, ELP_IO_EXTENT); ! 1517: } ! 1518: #endif /* MODULE */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.