|
|
1.1 ! root 1: /* 3c509.c: A 3c509 EtherLink3 ethernet driver for linux. */ ! 2: /* ! 3: Written 1993,1994 by Donald Becker. ! 4: ! 5: Copyright 1994 by Donald Becker. ! 6: Copyright 1993 United States Government as represented by the ! 7: Director, National Security Agency. This software may be used and ! 8: distributed according to the terms of the GNU Public License, ! 9: incorporated herein by reference. ! 10: ! 11: This driver is for the 3Com EtherLinkIII series. ! 12: ! 13: The author may be reached as [email protected] or ! 14: C/O Center of Excellence in Space Data and Information Sciences ! 15: Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771 ! 16: ! 17: Known limitations: ! 18: Because of the way 3c509 ISA detection works it's difficult to predict ! 19: a priori which of several ISA-mode cards will be detected first. ! 20: ! 21: This driver does not use predictive interrupt mode, resulting in higher ! 22: packet latency but lower overhead. If interrupts are disabled for an ! 23: unusually long time it could also result in missed packets, but in ! 24: practice this rarely happens. ! 25: */ ! 26: ! 27: static const char *version = "3c509.c:1.03 10/8/94 [email protected]\n"; ! 28: ! 29: #include <linux/module.h> ! 30: ! 31: #include <linux/config.h> ! 32: #include <linux/kernel.h> ! 33: #include <linux/sched.h> ! 34: #include <linux/string.h> ! 35: #include <linux/interrupt.h> ! 36: #include <linux/ptrace.h> ! 37: #include <linux/errno.h> ! 38: #include <linux/in.h> ! 39: #include <linux/malloc.h> ! 40: #include <linux/ioport.h> ! 41: #include <linux/netdevice.h> ! 42: #include <linux/etherdevice.h> ! 43: #include <linux/skbuff.h> ! 44: #include <linux/config.h> /* for CONFIG_MCA */ ! 45: ! 46: #include <asm/bitops.h> ! 47: #include <asm/io.h> ! 48: ! 49: ! 50: #ifdef EL3_DEBUG ! 51: int el3_debug = EL3_DEBUG; ! 52: #else ! 53: int el3_debug = 2; ! 54: #endif ! 55: ! 56: /* To minimize the size of the driver source I only define operating ! 57: constants if they are used several times. You'll need the manual ! 58: if you want to understand driver details. */ ! 59: /* Offsets from base I/O address. */ ! 60: #define EL3_DATA 0x00 ! 61: #define EL3_CMD 0x0e ! 62: #define EL3_STATUS 0x0e ! 63: #define ID_PORT 0x100 ! 64: #define EEPROM_READ 0x80 ! 65: ! 66: #define EL3_IO_EXTENT 16 ! 67: ! 68: #define EL3WINDOW(win_num) outw(SelectWindow + (win_num), ioaddr + EL3_CMD) ! 69: ! 70: ! 71: /* The top five bits written to EL3_CMD are a command, the lower ! 72: 11 bits are the parameter, if applicable. */ ! 73: enum c509cmd { ! 74: TotalReset = 0<<11, SelectWindow = 1<<11, StartCoax = 2<<11, ! 75: RxDisable = 3<<11, RxEnable = 4<<11, RxReset = 5<<11, RxDiscard = 8<<11, ! 76: TxEnable = 9<<11, TxDisable = 10<<11, TxReset = 11<<11, ! 77: FakeIntr = 12<<11, AckIntr = 13<<11, SetIntrMask = 14<<11, ! 78: SetReadZero = 15<<11, SetRxFilter = 16<<11, SetRxThreshold = 17<<11, ! 79: SetTxThreshold = 18<<11, SetTxStart = 19<<11, StatsEnable = 21<<11, ! 80: StatsDisable = 22<<11, StopCoax = 23<<11,}; ! 81: ! 82: /* The SetRxFilter command accepts the following classes: */ ! 83: enum RxFilter { ! 84: RxStation = 1, RxMulticast = 2, RxBroadcast = 4, RxProm = 8 }; ! 85: ! 86: /* Register window 1 offsets, the window used in normal operation. */ ! 87: #define TX_FIFO 0x00 ! 88: #define RX_FIFO 0x00 ! 89: #define RX_STATUS 0x08 ! 90: #define TX_STATUS 0x0B ! 91: #define TX_FREE 0x0C /* Remaining free bytes in Tx buffer. */ ! 92: ! 93: #define WN0_IRQ 0x08 /* Window 0: Set IRQ line in bits 12-15. */ ! 94: #define WN4_MEDIA 0x0A /* Window 4: Various transcvr/media bits. */ ! 95: #define MEDIA_TP 0x00C0 /* Enable link beat and jabber for 10baseT. */ ! 96: ! 97: struct el3_private { ! 98: struct enet_statistics stats; ! 99: }; ! 100: ! 101: static ushort id_read_eeprom(int index); ! 102: static ushort read_eeprom(short ioaddr, int index); ! 103: static int el3_open(struct device *dev); ! 104: static int el3_start_xmit(struct sk_buff *skb, struct device *dev); ! 105: static void el3_interrupt(int irq, struct pt_regs *regs); ! 106: static void update_stats(int addr, struct device *dev); ! 107: static struct enet_statistics *el3_get_stats(struct device *dev); ! 108: static int el3_rx(struct device *dev); ! 109: static int el3_close(struct device *dev); ! 110: static void set_multicast_list(struct device *dev); ! 111: ! 112: ! 113: ! 114: int el3_probe(struct device *dev) ! 115: { ! 116: short lrs_state = 0xff, i; ! 117: ushort ioaddr, irq, if_port; ! 118: short *phys_addr = (short *)dev->dev_addr; ! 119: static int current_tag = 0; ! 120: ! 121: /* First check all slots of the EISA bus. The next slot address to ! 122: probe is kept in 'eisa_addr' to support multiple probe() calls. */ ! 123: if (EISA_bus) { ! 124: static int eisa_addr = 0x1000; ! 125: while (eisa_addr < 0x9000) { ! 126: ioaddr = eisa_addr; ! 127: eisa_addr += 0x1000; ! 128: ! 129: /* Check the standard EISA ID register for an encoded '3Com'. */ ! 130: if (inw(ioaddr + 0xC80) != 0x6d50) ! 131: continue; ! 132: ! 133: /* Change the register set to the configuration window 0. */ ! 134: outw(SelectWindow | 0, ioaddr + 0xC80 + EL3_CMD); ! 135: ! 136: irq = inw(ioaddr + WN0_IRQ) >> 12; ! 137: if_port = inw(ioaddr + 6)>>14; ! 138: for (i = 0; i < 3; i++) ! 139: phys_addr[i] = htons(read_eeprom(ioaddr, i)); ! 140: ! 141: /* Restore the "Product ID" to the EEPROM read register. */ ! 142: read_eeprom(ioaddr, 3); ! 143: ! 144: /* Was the EISA code an add-on hack? Nahhhhh... */ ! 145: goto found; ! 146: } ! 147: } ! 148: ! 149: #ifdef CONFIG_MCA ! 150: if (MCA_bus) { ! 151: mca_adaptor_select_mode(1); ! 152: for (i = 0; i < 8; i++) ! 153: if ((mca_adaptor_id(i) | 1) == 0x627c) { ! 154: ioaddr = mca_pos_base_addr(i); ! 155: irq = inw(ioaddr + WN0_IRQ) >> 12; ! 156: if_port = inw(ioaddr + 6)>>14; ! 157: for (i = 0; i < 3; i++) ! 158: phys_addr[i] = htons(read_eeprom(ioaddr, i)); ! 159: ! 160: mca_adaptor_select_mode(0); ! 161: goto found; ! 162: } ! 163: mca_adaptor_select_mode(0); ! 164: ! 165: } ! 166: #endif ! 167: ! 168: /* Next check for all ISA bus boards by sending the ID sequence to the ! 169: ID_PORT. We find cards past the first by setting the 'current_tag' ! 170: on cards as they are found. Cards with their tag set will not ! 171: respond to subsequent ID sequences. */ ! 172: ! 173: if (check_region(ID_PORT,1)) { ! 174: static int once = 1; ! 175: if (once) printk("3c509: Somebody has reserved 0x%x, can't do ID_PORT lookup, nor card auto-probing\n",ID_PORT); ! 176: once = 0; ! 177: return -ENODEV; ! 178: } ! 179: ! 180: outb(0x00, ID_PORT); ! 181: outb(0x00, ID_PORT); ! 182: for(i = 0; i < 255; i++) { ! 183: outb(lrs_state, ID_PORT); ! 184: lrs_state <<= 1; ! 185: lrs_state = lrs_state & 0x100 ? lrs_state ^ 0xcf : lrs_state; ! 186: } ! 187: ! 188: /* For the first probe, clear all board's tag registers. */ ! 189: if (current_tag == 0) ! 190: outb(0xd0, ID_PORT); ! 191: else /* Otherwise kill off already-found boards. */ ! 192: outb(0xd8, ID_PORT); ! 193: ! 194: if (id_read_eeprom(7) != 0x6d50) { ! 195: return -ENODEV; ! 196: } ! 197: ! 198: /* Read in EEPROM data, which does contention-select. ! 199: Only the lowest address board will stay "on-line". ! 200: 3Com got the byte order backwards. */ ! 201: for (i = 0; i < 3; i++) { ! 202: phys_addr[i] = htons(id_read_eeprom(i)); ! 203: } ! 204: ! 205: { ! 206: unsigned short iobase = id_read_eeprom(8); ! 207: if_port = iobase >> 14; ! 208: ioaddr = 0x200 + ((iobase & 0x1f) << 4); ! 209: } ! 210: irq = id_read_eeprom(9) >> 12; ! 211: ! 212: if (dev->base_addr != 0 ! 213: && dev->base_addr != (unsigned short)ioaddr) { ! 214: return -ENODEV; ! 215: } ! 216: ! 217: /* Set the adaptor tag so that the next card can be found. */ ! 218: outb(0xd0 + ++current_tag, ID_PORT); ! 219: ! 220: /* Activate the adaptor at the EEPROM location. */ ! 221: outb(0xff, ID_PORT); ! 222: ! 223: EL3WINDOW(0); ! 224: if (inw(ioaddr) != 0x6d50) ! 225: return -ENODEV; ! 226: ! 227: /* Free the interrupt so that some other card can use it. */ ! 228: outw(0x0f00, ioaddr + WN0_IRQ); ! 229: found: ! 230: dev->base_addr = ioaddr; ! 231: dev->irq = irq; ! 232: dev->if_port = if_port; ! 233: request_region(dev->base_addr, EL3_IO_EXTENT, "3c509"); ! 234: ! 235: { ! 236: const char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"}; ! 237: printk("%s: 3c509 at %#3.3lx tag %d, %s port, address ", ! 238: dev->name, dev->base_addr, current_tag, if_names[dev->if_port]); ! 239: } ! 240: ! 241: /* Read in the station address. */ ! 242: for (i = 0; i < 6; i++) ! 243: printk(" %2.2x", dev->dev_addr[i]); ! 244: printk(", IRQ %d.\n", dev->irq); ! 245: ! 246: /* Make up a EL3-specific-data structure. */ ! 247: dev->priv = kmalloc(sizeof(struct el3_private), GFP_KERNEL); ! 248: if (dev->priv == NULL) ! 249: return -ENOMEM; ! 250: memset(dev->priv, 0, sizeof(struct el3_private)); ! 251: ! 252: if (el3_debug > 0) ! 253: printk(version); ! 254: ! 255: /* The EL3-specific entries in the device structure. */ ! 256: dev->open = &el3_open; ! 257: dev->hard_start_xmit = &el3_start_xmit; ! 258: dev->stop = &el3_close; ! 259: dev->get_stats = &el3_get_stats; ! 260: dev->set_multicast_list = &set_multicast_list; ! 261: ! 262: /* Fill in the generic fields of the device structure. */ ! 263: ether_setup(dev); ! 264: return 0; ! 265: } ! 266: ! 267: /* Read a word from the EEPROM using the regular EEPROM access register. ! 268: Assume that we are in register window zero. ! 269: */ ! 270: static ushort read_eeprom(short ioaddr, int index) ! 271: { ! 272: int timer; ! 273: ! 274: outw(EEPROM_READ + index, ioaddr + 10); ! 275: /* Pause for at least 162 us. for the read to take place. */ ! 276: for (timer = 0; timer < 162*4 + 400; timer++) ! 277: SLOW_DOWN_IO; ! 278: return inw(ioaddr + 12); ! 279: } ! 280: ! 281: /* Read a word from the EEPROM when in the ISA ID probe state. */ ! 282: static ushort id_read_eeprom(int index) ! 283: { ! 284: int timer, bit, word = 0; ! 285: ! 286: /* Issue read command, and pause for at least 162 us. for it to complete. ! 287: Assume extra-fast 16Mhz bus. */ ! 288: outb(EEPROM_READ + index, ID_PORT); ! 289: ! 290: /* This should really be done by looking at one of the timer channels. */ ! 291: for (timer = 0; timer < 162*4 + 400; timer++) ! 292: SLOW_DOWN_IO; ! 293: ! 294: for (bit = 15; bit >= 0; bit--) ! 295: word = (word << 1) + (inb(ID_PORT) & 0x01); ! 296: ! 297: if (el3_debug > 3) ! 298: printk(" 3c509 EEPROM word %d %#4.4x.\n", index, word); ! 299: ! 300: return word; ! 301: } ! 302: ! 303: ! 304: ! 305: static int ! 306: el3_open(struct device *dev) ! 307: { ! 308: int ioaddr = dev->base_addr; ! 309: int i; ! 310: ! 311: outw(TxReset, ioaddr + EL3_CMD); ! 312: outw(RxReset, ioaddr + EL3_CMD); ! 313: outw(SetReadZero | 0x00, ioaddr + EL3_CMD); ! 314: ! 315: if (request_irq(dev->irq, &el3_interrupt, 0, "3c509")) { ! 316: return -EAGAIN; ! 317: } ! 318: ! 319: EL3WINDOW(0); ! 320: if (el3_debug > 3) ! 321: printk("%s: Opening, IRQ %d status@%x %4.4x.\n", dev->name, ! 322: dev->irq, ioaddr + EL3_STATUS, inw(ioaddr + EL3_STATUS)); ! 323: ! 324: /* Activate board: this is probably unnecessary. */ ! 325: outw(0x0001, ioaddr + 4); ! 326: ! 327: irq2dev_map[dev->irq] = dev; ! 328: ! 329: /* Set the IRQ line. */ ! 330: outw((dev->irq << 12) | 0x0f00, ioaddr + WN0_IRQ); ! 331: ! 332: /* Set the station address in window 2 each time opened. */ ! 333: EL3WINDOW(2); ! 334: ! 335: for (i = 0; i < 6; i++) ! 336: outb(dev->dev_addr[i], ioaddr + i); ! 337: ! 338: if (dev->if_port == 3) ! 339: /* Start the thinnet transceiver. We should really wait 50ms...*/ ! 340: outw(StartCoax, ioaddr + EL3_CMD); ! 341: else if (dev->if_port == 0) { ! 342: /* 10baseT interface, enabled link beat and jabber check. */ ! 343: EL3WINDOW(4); ! 344: outw(inw(ioaddr + WN4_MEDIA) | MEDIA_TP, ioaddr + WN4_MEDIA); ! 345: } ! 346: ! 347: /* Switch to the stats window, and clear all stats by reading. */ ! 348: outw(StatsDisable, ioaddr + EL3_CMD); ! 349: EL3WINDOW(6); ! 350: for (i = 0; i < 9; i++) ! 351: inb(ioaddr + i); ! 352: inb(ioaddr + 10); ! 353: inb(ioaddr + 12); ! 354: ! 355: /* Switch to register set 1 for normal use. */ ! 356: EL3WINDOW(1); ! 357: ! 358: /* Accept b-case and phys addr only. */ ! 359: outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD); ! 360: outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */ ! 361: ! 362: dev->interrupt = 0; ! 363: dev->tbusy = 0; ! 364: dev->start = 1; ! 365: ! 366: outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */ ! 367: outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */ ! 368: /* Allow status bits to be seen. */ ! 369: outw(SetReadZero | 0xff, ioaddr + EL3_CMD); ! 370: outw(AckIntr | 0x69, ioaddr + EL3_CMD); /* Ack IRQ */ ! 371: outw(SetIntrMask | 0x98, ioaddr + EL3_CMD); /* Set interrupt mask. */ ! 372: ! 373: if (el3_debug > 3) ! 374: printk("%s: Opened 3c509 IRQ %d status %4.4x.\n", ! 375: dev->name, dev->irq, inw(ioaddr + EL3_STATUS)); ! 376: ! 377: MOD_INC_USE_COUNT; ! 378: return 0; /* Always succeed */ ! 379: } ! 380: ! 381: static int ! 382: el3_start_xmit(struct sk_buff *skb, struct device *dev) ! 383: { ! 384: struct el3_private *lp = (struct el3_private *)dev->priv; ! 385: int ioaddr = dev->base_addr; ! 386: ! 387: /* Transmitter timeout, serious problems. */ ! 388: if (dev->tbusy) { ! 389: int tickssofar = jiffies - dev->trans_start; ! 390: if (tickssofar < 10) ! 391: return 1; ! 392: printk("%s: transmit timed out, tx_status %2.2x status %4.4x.\n", ! 393: dev->name, inb(ioaddr + TX_STATUS), inw(ioaddr + EL3_STATUS)); ! 394: dev->trans_start = jiffies; ! 395: /* Issue TX_RESET and TX_START commands. */ ! 396: outw(TxReset, ioaddr + EL3_CMD); ! 397: outw(TxEnable, ioaddr + EL3_CMD); ! 398: dev->tbusy = 0; ! 399: } ! 400: ! 401: if (skb == NULL) { ! 402: dev_tint(dev); ! 403: return 0; ! 404: } ! 405: ! 406: if (skb->len <= 0) ! 407: return 0; ! 408: ! 409: if (el3_debug > 4) { ! 410: printk("%s: el3_start_xmit(length = %ld) called, status %4.4x.\n", ! 411: dev->name, skb->len, inw(ioaddr + EL3_STATUS)); ! 412: } ! 413: #ifndef final_version ! 414: { /* Error-checking code, delete for 1.30. */ ! 415: ushort status = inw(ioaddr + EL3_STATUS); ! 416: if (status & 0x0001 /* IRQ line active, missed one. */ ! 417: && inw(ioaddr + EL3_STATUS) & 1) { /* Make sure. */ ! 418: printk("%s: Missed interrupt, status then %04x now %04x" ! 419: " Tx %2.2x Rx %4.4x.\n", dev->name, status, ! 420: inw(ioaddr + EL3_STATUS), inb(ioaddr + TX_STATUS), ! 421: inw(ioaddr + RX_STATUS)); ! 422: /* Fake interrupt trigger by masking, acknowledge interrupts. */ ! 423: outw(SetReadZero | 0x00, ioaddr + EL3_CMD); ! 424: outw(AckIntr | 0x69, ioaddr + EL3_CMD); /* Ack IRQ */ ! 425: outw(SetReadZero | 0xff, ioaddr + EL3_CMD); ! 426: } ! 427: } ! 428: #endif ! 429: ! 430: /* Avoid timer-based retransmission conflicts. */ ! 431: if (set_bit(0, (void*)&dev->tbusy) != 0) ! 432: printk("%s: Transmitter access conflict.\n", dev->name); ! 433: else { ! 434: /* Put out the doubleword header... */ ! 435: outw(skb->len, ioaddr + TX_FIFO); ! 436: outw(0x00, ioaddr + TX_FIFO); ! 437: /* ... and the packet rounded to a doubleword. */ ! 438: outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2); ! 439: ! 440: dev->trans_start = jiffies; ! 441: if (inw(ioaddr + TX_FREE) > 1536) { ! 442: dev->tbusy = 0; ! 443: } else ! 444: /* Interrupt us when the FIFO has room for max-sized packet. */ ! 445: outw(SetTxThreshold + 1536, ioaddr + EL3_CMD); ! 446: } ! 447: ! 448: dev_kfree_skb (skb, FREE_WRITE); ! 449: ! 450: /* Clear the Tx status stack. */ ! 451: { ! 452: short tx_status; ! 453: int i = 4; ! 454: ! 455: while (--i > 0 && (tx_status = inb(ioaddr + TX_STATUS)) > 0) { ! 456: if (tx_status & 0x38) lp->stats.tx_aborted_errors++; ! 457: if (tx_status & 0x30) outw(TxReset, ioaddr + EL3_CMD); ! 458: if (tx_status & 0x3C) outw(TxEnable, ioaddr + EL3_CMD); ! 459: outb(0x00, ioaddr + TX_STATUS); /* Pop the status stack. */ ! 460: } ! 461: } ! 462: return 0; ! 463: } ! 464: ! 465: /* The EL3 interrupt handler. */ ! 466: static void ! 467: el3_interrupt(int irq, struct pt_regs *regs) ! 468: { ! 469: struct device *dev = (struct device *)(irq2dev_map[irq]); ! 470: int ioaddr, status; ! 471: int i = 0; ! 472: ! 473: if (dev == NULL) { ! 474: printk ("el3_interrupt(): irq %d for unknown device.\n", irq); ! 475: return; ! 476: } ! 477: ! 478: if (dev->interrupt) ! 479: printk("%s: Re-entering the interrupt handler.\n", dev->name); ! 480: dev->interrupt = 1; ! 481: ! 482: ioaddr = dev->base_addr; ! 483: status = inw(ioaddr + EL3_STATUS); ! 484: ! 485: if (el3_debug > 4) ! 486: printk("%s: interrupt, status %4.4x.\n", dev->name, status); ! 487: ! 488: while ((status = inw(ioaddr + EL3_STATUS)) & 0x91) { ! 489: ! 490: if (status & 0x10) ! 491: el3_rx(dev); ! 492: ! 493: if (status & 0x08) { ! 494: if (el3_debug > 5) ! 495: printk(" TX room bit was handled.\n"); ! 496: /* There's room in the FIFO for a full-sized packet. */ ! 497: outw(AckIntr | 0x08, ioaddr + EL3_CMD); ! 498: dev->tbusy = 0; ! 499: mark_bh(NET_BH); ! 500: } ! 501: if (status & 0x80) /* Statistics full. */ ! 502: update_stats(ioaddr, dev); ! 503: ! 504: if (++i > 10) { ! 505: printk("%s: Infinite loop in interrupt, status %4.4x.\n", ! 506: dev->name, status); ! 507: /* Clear all interrupts. */ ! 508: outw(AckIntr | 0xFF, ioaddr + EL3_CMD); ! 509: break; ! 510: } ! 511: /* Acknowledge the IRQ. */ ! 512: outw(AckIntr | 0x41, ioaddr + EL3_CMD); /* Ack IRQ */ ! 513: ! 514: } ! 515: ! 516: if (el3_debug > 4) { ! 517: printk("%s: exiting interrupt, status %4.4x.\n", dev->name, ! 518: inw(ioaddr + EL3_STATUS)); ! 519: } ! 520: ! 521: dev->interrupt = 0; ! 522: return; ! 523: } ! 524: ! 525: ! 526: static struct enet_statistics * ! 527: el3_get_stats(struct device *dev) ! 528: { ! 529: struct el3_private *lp = (struct el3_private *)dev->priv; ! 530: unsigned long flags; ! 531: ! 532: save_flags(flags); ! 533: cli(); ! 534: update_stats(dev->base_addr, dev); ! 535: restore_flags(flags); ! 536: return &lp->stats; ! 537: } ! 538: ! 539: /* Update statistics. We change to register window 6, so this should be run ! 540: single-threaded if the device is active. This is expected to be a rare ! 541: operation, and it's simpler for the rest of the driver to assume that ! 542: window 1 is always valid rather than use a special window-state variable. ! 543: */ ! 544: static void update_stats(int ioaddr, struct device *dev) ! 545: { ! 546: struct el3_private *lp = (struct el3_private *)dev->priv; ! 547: ! 548: if (el3_debug > 5) ! 549: printk(" Updating the statistics.\n"); ! 550: /* Turn off statistics updates while reading. */ ! 551: outw(StatsDisable, ioaddr + EL3_CMD); ! 552: /* Switch to the stats window, and read everything. */ ! 553: EL3WINDOW(6); ! 554: lp->stats.tx_carrier_errors += inb(ioaddr + 0); ! 555: lp->stats.tx_heartbeat_errors += inb(ioaddr + 1); ! 556: /* Multiple collisions. */ inb(ioaddr + 2); ! 557: lp->stats.collisions += inb(ioaddr + 3); ! 558: lp->stats.tx_window_errors += inb(ioaddr + 4); ! 559: lp->stats.rx_fifo_errors += inb(ioaddr + 5); ! 560: lp->stats.tx_packets += inb(ioaddr + 6); ! 561: /* Rx packets */ inb(ioaddr + 7); ! 562: /* Tx deferrals */ inb(ioaddr + 8); ! 563: inw(ioaddr + 10); /* Total Rx and Tx octets. */ ! 564: inw(ioaddr + 12); ! 565: ! 566: /* Back to window 1, and turn statistics back on. */ ! 567: EL3WINDOW(1); ! 568: outw(StatsEnable, ioaddr + EL3_CMD); ! 569: return; ! 570: } ! 571: ! 572: static int ! 573: el3_rx(struct device *dev) ! 574: { ! 575: struct el3_private *lp = (struct el3_private *)dev->priv; ! 576: int ioaddr = dev->base_addr; ! 577: short rx_status; ! 578: ! 579: if (el3_debug > 5) ! 580: printk(" In rx_packet(), status %4.4x, rx_status %4.4x.\n", ! 581: inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS)); ! 582: while ((rx_status = inw(ioaddr + RX_STATUS)) > 0) { ! 583: if (rx_status & 0x4000) { /* Error, update stats. */ ! 584: short error = rx_status & 0x3800; ! 585: lp->stats.rx_errors++; ! 586: switch (error) { ! 587: case 0x0000: lp->stats.rx_over_errors++; break; ! 588: case 0x0800: lp->stats.rx_length_errors++; break; ! 589: case 0x1000: lp->stats.rx_frame_errors++; break; ! 590: case 0x1800: lp->stats.rx_length_errors++; break; ! 591: case 0x2000: lp->stats.rx_frame_errors++; break; ! 592: case 0x2800: lp->stats.rx_crc_errors++; break; ! 593: } ! 594: } else { ! 595: short pkt_len = rx_status & 0x7ff; ! 596: struct sk_buff *skb; ! 597: ! 598: skb = dev_alloc_skb(pkt_len+5); ! 599: if (el3_debug > 4) ! 600: printk("Receiving packet size %d status %4.4x.\n", ! 601: pkt_len, rx_status); ! 602: if (skb != NULL) { ! 603: skb->dev = dev; ! 604: skb_reserve(skb,2); /* Align IP on 16 byte boundaries */ ! 605: ! 606: /* 'skb->data' points to the start of sk_buff data area. */ ! 607: insl(ioaddr+RX_FIFO, skb_put(skb,pkt_len), ! 608: (pkt_len + 3) >> 2); ! 609: ! 610: skb->protocol=eth_type_trans(skb,dev); ! 611: netif_rx(skb); ! 612: outw(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */ ! 613: lp->stats.rx_packets++; ! 614: continue; ! 615: } else if (el3_debug) ! 616: printk("%s: Couldn't allocate a sk_buff of size %d.\n", ! 617: dev->name, pkt_len); ! 618: } ! 619: lp->stats.rx_dropped++; ! 620: outw(RxDiscard, ioaddr + EL3_CMD); ! 621: while (inw(ioaddr + EL3_STATUS) & 0x1000) ! 622: printk(" Waiting for 3c509 to discard packet, status %x.\n", ! 623: inw(ioaddr + EL3_STATUS) ); ! 624: } ! 625: ! 626: return 0; ! 627: } ! 628: ! 629: /* ! 630: * Set or clear the multicast filter for this adaptor. ! 631: */ ! 632: ! 633: static void set_multicast_list(struct device *dev) ! 634: { ! 635: short ioaddr = dev->base_addr; ! 636: if (el3_debug > 1) { ! 637: static int old = 0; ! 638: if (old != dev->mc_count) { ! 639: old = dev->mc_count; ! 640: printk("%s: Setting Rx mode to %d addresses.\n", dev->name, dev->mc_count); ! 641: } ! 642: } ! 643: if (dev->flags&IFF_PROMISC) ! 644: { ! 645: outw(SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm, ! 646: ioaddr + EL3_CMD); ! 647: } ! 648: else if (dev->mc_count || (dev->flags&IFF_ALLMULTI)) ! 649: { ! 650: outw(SetRxFilter|RxStation|RxMulticast|RxBroadcast, ioaddr + EL3_CMD); ! 651: } ! 652: else ! 653: outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD); ! 654: } ! 655: ! 656: static int ! 657: el3_close(struct device *dev) ! 658: { ! 659: int ioaddr = dev->base_addr; ! 660: ! 661: if (el3_debug > 2) ! 662: printk("%s: Shutting down ethercard.\n", dev->name); ! 663: ! 664: dev->tbusy = 1; ! 665: dev->start = 0; ! 666: ! 667: /* Turn off statistics ASAP. We update lp->stats below. */ ! 668: outw(StatsDisable, ioaddr + EL3_CMD); ! 669: ! 670: /* Disable the receiver and transmitter. */ ! 671: outw(RxDisable, ioaddr + EL3_CMD); ! 672: outw(TxDisable, ioaddr + EL3_CMD); ! 673: ! 674: if (dev->if_port == 3) ! 675: /* Turn off thinnet power. Green! */ ! 676: outw(StopCoax, ioaddr + EL3_CMD); ! 677: else if (dev->if_port == 0) { ! 678: /* Disable link beat and jabber, if_port may change ere next open(). */ ! 679: EL3WINDOW(4); ! 680: outw(inw(ioaddr + WN4_MEDIA) & ~MEDIA_TP, ioaddr + WN4_MEDIA); ! 681: } ! 682: ! 683: free_irq(dev->irq); ! 684: /* Switching back to window 0 disables the IRQ. */ ! 685: EL3WINDOW(0); ! 686: /* But we explicitly zero the IRQ line select anyway. */ ! 687: outw(0x0f00, ioaddr + WN0_IRQ); ! 688: ! 689: ! 690: irq2dev_map[dev->irq] = 0; ! 691: ! 692: update_stats(ioaddr, dev); ! 693: MOD_DEC_USE_COUNT; ! 694: return 0; ! 695: } ! 696: ! 697: #ifdef MODULE ! 698: static char devicename[9] = { 0, }; ! 699: static struct device dev_3c509 = { ! 700: devicename, /* device name is inserted by linux/drivers/net/net_init.c */ ! 701: 0, 0, 0, 0, ! 702: 0, 0, ! 703: 0, 0, 0, NULL, el3_probe }; ! 704: ! 705: static int io = 0; ! 706: static int irq = 0; ! 707: ! 708: int ! 709: init_module(void) ! 710: { ! 711: dev_3c509.base_addr = io; ! 712: dev_3c509.irq = irq; ! 713: if (!EISA_bus) { ! 714: printk("3c509: WARNING! Module load-time probing works reliably only for EISA-bus!\n"); ! 715: } ! 716: if (register_netdev(&dev_3c509) != 0) ! 717: return -EIO; ! 718: return 0; ! 719: } ! 720: ! 721: void ! 722: cleanup_module(void) ! 723: { ! 724: unregister_netdev(&dev_3c509); ! 725: kfree_s(dev_3c509.priv,sizeof(struct el3_private)); ! 726: dev_3c509.priv=NULL; ! 727: /* If we don't do this, we can't re-insmod it later. */ ! 728: release_region(dev_3c509.base_addr, EL3_IO_EXTENT); ! 729: } ! 730: #endif /* MODULE */ ! 731: ! 732: /* ! 733: * Local variables: ! 734: * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c 3c509.c" ! 735: * version-control: t ! 736: * kept-new-versions: 5 ! 737: * tab-width: 4 ! 738: * End: ! 739: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.