|
|
1.1 ! root 1: /* eth16i.c An ICL EtherTeam 16i and 32 EISA ethernet driver for Linux ! 2: ! 3: Written 1994-1998 by Mika Kuoppala ! 4: ! 5: Copyright (C) 1994-1998 by Mika Kuoppala ! 6: Based on skeleton.c and heavily on at1700.c by Donald Becker ! 7: ! 8: This software may be used and distributed according to the terms ! 9: of the GNU Public Licence, incorporated herein by reference. ! 10: ! 11: The author may be reached as [email protected] ! 12: ! 13: This driver supports following cards : ! 14: - ICL EtherTeam 16i ! 15: - ICL EtherTeam 32 EISA ! 16: (Uses true 32 bit transfers rather than 16i compability mode) ! 17: ! 18: Example Module usage: ! 19: insmod eth16i.o ioaddr=0x2a0 mediatype=bnc ! 20: ! 21: mediatype can be one of the following: bnc,tp,dix,auto,eprom ! 22: ! 23: 'auto' will try to autoprobe mediatype. ! 24: 'eprom' will use whatever type defined in eprom. ! 25: ! 26: I have benchmarked driver with PII/300Mhz as a ftp client ! 27: and 486/33Mhz as a ftp server. Top speed was 1128.37 kilobytes/sec. ! 28: ! 29: Sources: ! 30: - skeleton.c a sample network driver core for linux, ! 31: written by Donald Becker <[email protected]> ! 32: - at1700.c a driver for Allied Telesis AT1700, written ! 33: by Donald Becker. ! 34: - e16iSRV.asm a Netware 3.X Server Driver for ICL EtherTeam16i ! 35: written by Markku Viima ! 36: - The Fujitsu MB86965 databook. ! 37: ! 38: Author thanks following persons due to their valueble assistance: ! 39: Markku Viima (ICL) ! 40: Ari Valve (ICL) ! 41: Donald Becker ! 42: Kurt Huwig <[email protected]> ! 43: ! 44: Revision history: ! 45: ! 46: Version Date Description ! 47: ! 48: 0.01 15.12-94 Initial version (card detection) ! 49: 0.02 23.01-95 Interrupt is now hooked correctly ! 50: 0.03 01.02-95 Rewrote initialization part ! 51: 0.04 07.02-95 Base skeleton done... ! 52: Made a few changes to signature checking ! 53: to make it a bit reliable. ! 54: - fixed bug in tx_buf mapping ! 55: - fixed bug in initialization (DLC_EN ! 56: wasn't enabled when initialization ! 57: was done.) ! 58: 0.05 08.02-95 If there were more than one packet to send, ! 59: transmit was jammed due to invalid ! 60: register write...now fixed ! 61: 0.06 19.02-95 Rewrote interrupt handling ! 62: 0.07 13.04-95 Wrote EEPROM read routines ! 63: Card configuration now set according to ! 64: data read from EEPROM ! 65: 0.08 23.06-95 Wrote part that tries to probe used interface ! 66: port if AUTO is selected ! 67: ! 68: 0.09 01.09-95 Added module support ! 69: ! 70: 0.10 04.09-95 Fixed receive packet allocation to work ! 71: with kernels > 1.3.x ! 72: ! 73: 0.20 20.09-95 Added support for EtherTeam32 EISA ! 74: ! 75: 0.21 17.10-95 Removed the unnecessary extern ! 76: init_etherdev() declaration. Some ! 77: other cleanups. ! 78: ! 79: 0.22 22.02-96 Receive buffer was not flushed ! 80: correctly when faulty packet was ! 81: received. Now fixed. ! 82: ! 83: 0.23 26.02-96 Made resetting the adapter ! 84: more reliable. ! 85: ! 86: 0.24 27.02-96 Rewrote faulty packet handling in eth16i_rx ! 87: ! 88: 0.25 22.05-96 kfree() was missing from cleanup_module. ! 89: ! 90: 0.26 11.06-96 Sometimes card was not found by ! 91: check_signature(). Now made more reliable. ! 92: ! 93: 0.27 23.06-96 Oops. 16 consecutive collisions halted ! 94: adapter. Now will try to retransmit ! 95: MAX_COL_16 times before finally giving up. ! 96: ! 97: 0.28 28.10-97 Added dev_id parameter (NULL) for free_irq ! 98: ! 99: 0.29 29.10-97 Multiple card support for module users ! 100: ! 101: 0.30 30.10-97 Fixed irq allocation bug. ! 102: (request_irq moved from probe to open) ! 103: ! 104: 0.30a 21.08-98 Card detection made more relaxed. Driver ! 105: had problems with some TCP/IP-PROM boots ! 106: to find the card. Suggested by ! 107: Kurt Huwig <[email protected]> ! 108: ! 109: 0.31 28.08-98 Media interface port can now be selected ! 110: with module parameters or kernel ! 111: boot parameters. ! 112: ! 113: 0.32 31.08-98 IRQ was never freed if open/close ! 114: pair wasn't called. Now fixed. ! 115: ! 116: 0.33 10.09-98 When eth16i_open() was called after ! 117: eth16i_close() chip never recovered. ! 118: Now more shallow reset is made on ! 119: close. ! 120: ! 121: Bugs: ! 122: In some cases the media interface autoprobing code doesn't find ! 123: the correct interface type. In this case you can ! 124: manually choose the interface type in DOS with E16IC.EXE which is ! 125: configuration software for EtherTeam16i and EtherTeam32 cards. ! 126: This is also true for IRQ setting. You cannot use module ! 127: parameter to configure IRQ of the card (yet). ! 128: ! 129: To do: ! 130: - Real multicast support ! 131: - Rewrite the media interface autoprobing code. Its _horrible_ ! ! 132: - Possibly merge all the MB86965 specific code to external ! 133: module for use by eth16.c and Donald's at1700.c ! 134: - IRQ configuration with module parameter. I will do ! 135: this when i will get enough info about setting ! 136: irq without configuration utility. ! 137: */ ! 138: ! 139: static char *version = ! 140: "eth16i.c: v0.33 10-09-98 Mika Kuoppala ([email protected])\n"; ! 141: ! 142: #include <linux/module.h> ! 143: ! 144: #include <linux/kernel.h> ! 145: #include <linux/sched.h> ! 146: #include <linux/types.h> ! 147: #include <linux/fcntl.h> ! 148: #include <linux/interrupt.h> ! 149: #include <linux/ptrace.h> ! 150: #include <linux/ioport.h> ! 151: #include <linux/in.h> ! 152: #include <linux/malloc.h> ! 153: #include <linux/string.h> ! 154: #include <linux/errno.h> ! 155: ! 156: #include <linux/netdevice.h> ! 157: #include <linux/etherdevice.h> ! 158: #include <linux/skbuff.h> ! 159: ! 160: #include <asm/system.h> ! 161: #include <asm/bitops.h> ! 162: #include <asm/io.h> ! 163: #include <asm/dma.h> ! 164: ! 165: #ifndef LINUX_VERSION_CODE ! 166: #include <linux/version.h> ! 167: #endif ! 168: ! 169: #if LINUX_VERSION_CODE >= 0x20123 ! 170: #include <linux/init.h> ! 171: #else ! 172: #define __init ! 173: #define __initdata ! 174: #define __initfunc(x) x ! 175: #endif ! 176: ! 177: #if LINUX_VERSION_CODE < 0x20138 ! 178: #define test_and_set_bit(val,addr) set_bit(val,addr) ! 179: #endif ! 180: ! 181: #if LINUX_VERSION_CODE < 0x020100 ! 182: typedef struct enet_statistics eth16i_stats_type; ! 183: #else ! 184: typedef struct net_device_stats eth16i_stats_type; ! 185: #endif ! 186: ! 187: /* Few macros */ ! 188: #define BIT(a) ( (1 << (a)) ) ! 189: #define BITSET(ioaddr, bnum) ((outb(((inb(ioaddr)) | (bnum)), ioaddr))) ! 190: #define BITCLR(ioaddr, bnum) ((outb(((inb(ioaddr)) & (~(bnum))), ioaddr))) ! 191: ! 192: /* This is the I/O address space for Etherteam 16i adapter. */ ! 193: #define ETH16I_IO_EXTENT 32 ! 194: ! 195: /* Ticks before deciding that transmit has timed out */ ! 196: #define TX_TIMEOUT (400*HZ/1000) ! 197: ! 198: /* Maximum loop count when receiving packets */ ! 199: #define MAX_RX_LOOP 20 ! 200: ! 201: /* Some interrupt masks */ ! 202: #define ETH16I_INTR_ON 0xef8a /* Higher is receive mask */ ! 203: #define ETH16I_INTR_OFF 0x0000 ! 204: ! 205: /* Buffers header status byte meanings */ ! 206: #define PKT_GOOD BIT(5) ! 207: #define PKT_GOOD_RMT BIT(4) ! 208: #define PKT_SHORT BIT(3) ! 209: #define PKT_ALIGN_ERR BIT(2) ! 210: #define PKT_CRC_ERR BIT(1) ! 211: #define PKT_RX_BUF_OVERFLOW BIT(0) ! 212: ! 213: /* Transmit status register (DLCR0) */ ! 214: #define TX_STATUS_REG 0 ! 215: #define TX_DONE BIT(7) ! 216: #define NET_BUSY BIT(6) ! 217: #define TX_PKT_RCD BIT(5) ! 218: #define CR_LOST BIT(4) ! 219: #define TX_JABBER_ERR BIT(3) ! 220: #define COLLISION BIT(2) ! 221: #define COLLISIONS_16 BIT(1) ! 222: ! 223: /* Receive status register (DLCR1) */ ! 224: #define RX_STATUS_REG 1 ! 225: #define RX_PKT BIT(7) /* Packet received */ ! 226: #define BUS_RD_ERR BIT(6) ! 227: #define SHORT_PKT_ERR BIT(3) ! 228: #define ALIGN_ERR BIT(2) ! 229: #define CRC_ERR BIT(1) ! 230: #define RX_BUF_OVERFLOW BIT(0) ! 231: ! 232: /* Transmit Interrupt Enable Register (DLCR2) */ ! 233: #define TX_INTR_REG 2 ! 234: #define TX_INTR_DONE BIT(7) ! 235: #define TX_INTR_COL BIT(2) ! 236: #define TX_INTR_16_COL BIT(1) ! 237: ! 238: /* Receive Interrupt Enable Register (DLCR3) */ ! 239: #define RX_INTR_REG 3 ! 240: #define RX_INTR_RECEIVE BIT(7) ! 241: #define RX_INTR_SHORT_PKT BIT(3) ! 242: #define RX_INTR_CRC_ERR BIT(1) ! 243: #define RX_INTR_BUF_OVERFLOW BIT(0) ! 244: ! 245: /* Transmit Mode Register (DLCR4) */ ! 246: #define TRANSMIT_MODE_REG 4 ! 247: #define LOOPBACK_CONTROL BIT(1) ! 248: #define CONTROL_OUTPUT BIT(2) ! 249: ! 250: /* Receive Mode Register (DLCR5) */ ! 251: #define RECEIVE_MODE_REG 5 ! 252: #define RX_BUFFER_EMPTY BIT(6) ! 253: #define ACCEPT_BAD_PACKETS BIT(5) ! 254: #define RECEIVE_SHORT_ADDR BIT(4) ! 255: #define ACCEPT_SHORT_PACKETS BIT(3) ! 256: #define REMOTE_RESET BIT(2) ! 257: ! 258: #define ADDRESS_FILTER_MODE BIT(1) | BIT(0) ! 259: #define REJECT_ALL 0 ! 260: #define ACCEPT_ALL 3 ! 261: #define MODE_1 1 /* NODE ID, BC, MC, 2-24th bit */ ! 262: #define MODE_2 2 /* NODE ID, BC, MC, Hash Table */ ! 263: ! 264: /* Configuration Register 0 (DLCR6) */ ! 265: #define CONFIG_REG_0 6 ! 266: #define DLC_EN BIT(7) ! 267: #define SRAM_CYCLE_TIME_100NS BIT(6) ! 268: #define SYSTEM_BUS_WIDTH_8 BIT(5) /* 1 = 8bit, 0 = 16bit */ ! 269: #define BUFFER_WIDTH_8 BIT(4) /* 1 = 8bit, 0 = 16bit */ ! 270: #define TBS1 BIT(3) ! 271: #define TBS0 BIT(2) ! 272: #define SRAM_BS1 BIT(1) /* 00=8kb, 01=16kb */ ! 273: #define SRAM_BS0 BIT(0) /* 10=32kb, 11=64kb */ ! 274: ! 275: #ifndef ETH16I_TX_BUF_SIZE /* 0 = 2kb, 1 = 4kb */ ! 276: #define ETH16I_TX_BUF_SIZE 3 /* 2 = 8kb, 3 = 16kb */ ! 277: #endif ! 278: #define TX_BUF_1x2048 0 ! 279: #define TX_BUF_2x2048 1 ! 280: #define TX_BUF_2x4098 2 ! 281: #define TX_BUF_2x8192 3 ! 282: ! 283: /* Configuration Register 1 (DLCR7) */ ! 284: #define CONFIG_REG_1 7 ! 285: #define POWERUP BIT(5) ! 286: ! 287: /* Transmit start register */ ! 288: #define TRANSMIT_START_REG 10 ! 289: #define TRANSMIT_START_RB 2 ! 290: #define TX_START BIT(7) /* Rest of register bit indicate*/ ! 291: /* number of packets in tx buffer*/ ! 292: /* Node ID registers (DLCR8-13) */ ! 293: #define NODE_ID_0 8 ! 294: #define NODE_ID_RB 0 ! 295: ! 296: /* Hash Table registers (HT8-15) */ ! 297: #define HASH_TABLE_0 8 ! 298: #define HASH_TABLE_RB 1 ! 299: ! 300: /* Buffer memory ports */ ! 301: #define BUFFER_MEM_PORT_LB 8 ! 302: #define DATAPORT BUFFER_MEM_PORT_LB ! 303: #define BUFFER_MEM_PORT_HB 9 ! 304: ! 305: /* 16 Collision control register (BMPR11) */ ! 306: #define COL_16_REG 11 ! 307: #define HALT_ON_16 0x00 ! 308: #define RETRANS_AND_HALT_ON_16 0x02 ! 309: ! 310: /* Maximum number of attempts to send after 16 concecutive collisions */ ! 311: #define MAX_COL_16 10 ! 312: ! 313: /* DMA Burst and Transceiver Mode Register (BMPR13) */ ! 314: #define TRANSCEIVER_MODE_REG 13 ! 315: #define TRANSCEIVER_MODE_RB 2 ! 316: #define IO_BASE_UNLOCK BIT(7) ! 317: #define LOWER_SQUELCH_TRESH BIT(6) ! 318: #define LINK_TEST_DISABLE BIT(5) ! 319: #define AUI_SELECT BIT(4) ! 320: #define DIS_AUTO_PORT_SEL BIT(3) ! 321: ! 322: /* Filter Self Receive Register (BMPR14) */ ! 323: #define FILTER_SELF_RX_REG 14 ! 324: #define SKIP_RX_PACKET BIT(2) ! 325: #define FILTER_SELF_RECEIVE BIT(0) ! 326: ! 327: /* EEPROM Control Register (BMPR 16) */ ! 328: #define EEPROM_CTRL_REG 16 ! 329: ! 330: /* EEPROM Data Register (BMPR 17) */ ! 331: #define EEPROM_DATA_REG 17 ! 332: ! 333: /* NMC93CSx6 EEPROM Control Bits */ ! 334: #define CS_0 0x00 ! 335: #define CS_1 0x20 ! 336: #define SK_0 0x00 ! 337: #define SK_1 0x40 ! 338: #define DI_0 0x00 ! 339: #define DI_1 0x80 ! 340: ! 341: /* NMC93CSx6 EEPROM Instructions */ ! 342: #define EEPROM_READ 0x80 ! 343: ! 344: /* NMC93CSx6 EEPROM Addresses */ ! 345: #define E_NODEID_0 0x02 ! 346: #define E_NODEID_1 0x03 ! 347: #define E_NODEID_2 0x04 ! 348: #define E_PORT_SELECT 0x14 ! 349: #define E_PORT_BNC 0x00 ! 350: #define E_PORT_DIX 0x01 ! 351: #define E_PORT_TP 0x02 ! 352: #define E_PORT_AUTO 0x03 ! 353: #define E_PORT_FROM_EPROM 0x04 ! 354: #define E_PRODUCT_CFG 0x30 ! 355: ! 356: ! 357: /* Macro to slow down io between EEPROM clock transitions */ ! 358: #define eeprom_slow_io() do { int _i = 40; while(--_i > 0) { inb(0x80); }}while(0) ! 359: ! 360: /* Jumperless Configuration Register (BMPR19) */ ! 361: #define JUMPERLESS_CONFIG 19 ! 362: ! 363: /* ID ROM registers, writing to them also resets some parts of chip */ ! 364: #define ID_ROM_0 24 ! 365: #define ID_ROM_7 31 ! 366: #define RESET ID_ROM_0 ! 367: ! 368: /* This is the I/O address list to be probed when seeking the card */ ! 369: static unsigned int eth16i_portlist[] = ! 370: { 0x260, 0x280, 0x2A0, 0x240, 0x340, 0x320, 0x380, 0x300, 0 }; ! 371: ! 372: static unsigned int eth32i_portlist[] = ! 373: { 0x1000, 0x2000, 0x3000, 0x4000, 0x5000, 0x6000, 0x7000, 0x8000, ! 374: 0x9000, 0xA000, 0xB000, 0xC000, 0xD000, 0xE000, 0xF000, 0 }; ! 375: ! 376: /* This is the Interrupt lookup table for Eth16i card */ ! 377: static unsigned int eth16i_irqmap[] = { 9, 10, 5, 15, 0 }; ! 378: #define NUM_OF_ISA_IRQS 4 ! 379: ! 380: /* This is the Interrupt lookup table for Eth32i card */ ! 381: static unsigned int eth32i_irqmap[] = { 3, 5, 7, 9, 10, 11, 12, 15, 0 }; ! 382: #define EISA_IRQ_REG 0xc89 ! 383: #define NUM_OF_EISA_IRQS 8 ! 384: ! 385: static unsigned int eth16i_tx_buf_map[] = { 2048, 2048, 4096, 8192 }; ! 386: static unsigned int boot = 1; ! 387: ! 388: /* Use 0 for production, 1 for verification, >2 for debug */ ! 389: #ifndef ETH16I_DEBUG ! 390: #define ETH16I_DEBUG 0 ! 391: #endif ! 392: static unsigned int eth16i_debug = ETH16I_DEBUG; ! 393: ! 394: /* Information for each board */ ! 395: ! 396: struct eth16i_local { ! 397: eth16i_stats_type stats; ! 398: unsigned char tx_started; ! 399: unsigned char tx_buf_busy; ! 400: unsigned short tx_queue; /* Number of packets in transmit buffer */ ! 401: unsigned short tx_queue_len; ! 402: unsigned int tx_buf_size; ! 403: unsigned long open_time; ! 404: unsigned long tx_buffered_packets; ! 405: unsigned long col_16; ! 406: }; ! 407: ! 408: /* Function prototypes */ ! 409: ! 410: extern int eth16i_probe(struct device *dev); ! 411: ! 412: static int eth16i_probe1(struct device *dev, int ioaddr); ! 413: static int eth16i_check_signature(int ioaddr); ! 414: static int eth16i_probe_port(int ioaddr); ! 415: static void eth16i_set_port(int ioaddr, int porttype); ! 416: static int eth16i_send_probe_packet(int ioaddr, unsigned char *b, int l); ! 417: static int eth16i_receive_probe_packet(int ioaddr); ! 418: static int eth16i_get_irq(int ioaddr); ! 419: static int eth16i_read_eeprom(int ioaddr, int offset); ! 420: static int eth16i_read_eeprom_word(int ioaddr); ! 421: static void eth16i_eeprom_cmd(int ioaddr, unsigned char command); ! 422: static int eth16i_open(struct device *dev); ! 423: static int eth16i_close(struct device *dev); ! 424: static int eth16i_tx(struct sk_buff *skb, struct device *dev); ! 425: static void eth16i_rx(struct device *dev); ! 426: static void eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs); ! 427: static void eth16i_reset(struct device *dev); ! 428: static void eth16i_skip_packet(struct device *dev); ! 429: static void eth16i_multicast(struct device *dev); ! 430: static void eth16i_select_regbank(unsigned char regbank, int ioaddr); ! 431: static void eth16i_initialize(struct device *dev); ! 432: ! 433: #if 0 ! 434: static int eth16i_set_irq(struct device *dev); ! 435: #endif ! 436: ! 437: #ifdef MODULE ! 438: static ushort eth16i_parse_mediatype(const char* s); ! 439: #endif ! 440: ! 441: static struct enet_statistics *eth16i_get_stats(struct device *dev); ! 442: ! 443: static char *cardname = "ICL EtherTeam 16i/32"; ! 444: ! 445: #ifdef HAVE_DEVLIST ! 446: ! 447: /* Support for alternate probe manager */ ! 448: /struct netdev_entry eth16i_drv = ! 449: {"eth16i", eth16i_probe1, ETH16I_IO_EXTENT, eth16i_probe_list}; ! 450: ! 451: #else /* Not HAVE_DEVLIST */ ! 452: ! 453: __initfunc(int eth16i_probe(struct device *dev)) ! 454: { ! 455: int i; ! 456: int ioaddr; ! 457: int base_addr = dev ? dev->base_addr : 0; ! 458: ! 459: if(eth16i_debug > 4) ! 460: printk(KERN_DEBUG "Probing started for %s\n", cardname); ! 461: ! 462: if(base_addr > 0x1ff) /* Check only single location */ ! 463: return eth16i_probe1(dev, base_addr); ! 464: else if(base_addr != 0) /* Don't probe at all */ ! 465: return ENXIO; ! 466: ! 467: /* Seek card from the ISA io address space */ ! 468: for(i = 0; (ioaddr = eth16i_portlist[i]) ; i++) { ! 469: if(check_region(ioaddr, ETH16I_IO_EXTENT)) ! 470: continue; ! 471: if(eth16i_probe1(dev, ioaddr) == 0) ! 472: return 0; ! 473: } ! 474: ! 475: /* Seek card from the EISA io address space */ ! 476: for(i = 0; (ioaddr = eth32i_portlist[i]) ; i++) { ! 477: if(check_region(ioaddr, ETH16I_IO_EXTENT)) ! 478: continue; ! 479: if(eth16i_probe1(dev, ioaddr) == 0) ! 480: return 0; ! 481: } ! 482: ! 483: return ENODEV; ! 484: } ! 485: #endif /* Not HAVE_DEVLIST */ ! 486: ! 487: __initfunc(static int eth16i_probe1(struct device *dev, int ioaddr)) ! 488: { ! 489: static unsigned version_printed = 0; ! 490: boot = 1; /* To inform initilization that we are in boot probe */ ! 491: ! 492: /* ! 493: The MB86985 chip has on register which holds information in which ! 494: io address the chip lies. First read this register and compare ! 495: it to our current io address and if match then this could ! 496: be our chip. ! 497: */ ! 498: ! 499: if(ioaddr < 0x1000) { ! 500: ! 501: if(eth16i_portlist[(inb(ioaddr + JUMPERLESS_CONFIG) & 0x07)] ! 502: != ioaddr) ! 503: return -ENODEV; ! 504: } ! 505: ! 506: /* Now we will go a bit deeper and try to find the chip's signature */ ! 507: ! 508: if(eth16i_check_signature(ioaddr) != 0) ! 509: return -ENODEV; ! 510: ! 511: /* ! 512: Now it seems that we have found a ethernet chip in this particular ! 513: ioaddr. The MB86985 chip has this feature, that when you read a ! 514: certain register it will increase it's io base address to next ! 515: configurable slot. Now when we have found the chip, first thing is ! 516: to make sure that the chip's ioaddr will hold still here. ! 517: */ ! 518: ! 519: eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr); ! 520: outb(0x00, ioaddr + TRANSCEIVER_MODE_REG); ! 521: ! 522: outb(0x00, ioaddr + RESET); /* Reset some parts of chip */ ! 523: BITSET(ioaddr + CONFIG_REG_0, BIT(7)); /* Disable the data link */ ! 524: ! 525: if(dev == NULL) ! 526: dev = init_etherdev(0, 0); ! 527: ! 528: if( (eth16i_debug & version_printed++) == 0) ! 529: printk(KERN_INFO "%s", version); ! 530: ! 531: dev->base_addr = ioaddr; ! 532: ! 533: #if 0 ! 534: if(dev->irq) { ! 535: if(eth16i_set_irq(dev)) { ! 536: dev->irq = eth16i_get_irq(ioaddr); ! 537: } ! 538: ! 539: } ! 540: else { ! 541: #endif ! 542: ! 543: dev->irq = eth16i_get_irq(ioaddr); ! 544: ! 545: /* Try to obtain interrupt vector */ ! 546: ! 547: if (request_irq(dev->irq, (void *)ð16i_interrupt, 0, "eth16i", dev)) { ! 548: printk(KERN_WARNING "%s: %s at %#3x, but is unusable due conflicting IRQ %d.\n", ! 549: dev->name, cardname, ioaddr, dev->irq); ! 550: return -EAGAIN; ! 551: } ! 552: ! 553: #if 0 ! 554: irq2dev_map[dev->irq] = dev; ! 555: #endif ! 556: ! 557: printk(KERN_INFO "%s: %s at %#3x, IRQ %d, ", ! 558: dev->name, cardname, ioaddr, dev->irq); ! 559: ! 560: /* Let's grab the region */ ! 561: request_region(ioaddr, ETH16I_IO_EXTENT, "eth16i"); ! 562: ! 563: /* Now we will have to lock the chip's io address */ ! 564: eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr); ! 565: outb(0x38, ioaddr + TRANSCEIVER_MODE_REG); ! 566: ! 567: eth16i_initialize(dev); /* Initialize rest of the chip's registers */ ! 568: ! 569: /* Now let's same some energy by shutting down the chip ;) */ ! 570: BITCLR(ioaddr + CONFIG_REG_1, POWERUP); ! 571: ! 572: /* Initialize the device structure */ ! 573: if(dev->priv == NULL) { ! 574: dev->priv = kmalloc(sizeof(struct eth16i_local), GFP_KERNEL); ! 575: if(dev->priv == NULL) ! 576: return -ENOMEM; ! 577: } ! 578: ! 579: memset(dev->priv, 0, sizeof(struct eth16i_local)); ! 580: ! 581: dev->open = eth16i_open; ! 582: dev->stop = eth16i_close; ! 583: dev->hard_start_xmit = eth16i_tx; ! 584: dev->get_stats = eth16i_get_stats; ! 585: dev->set_multicast_list = ð16i_multicast; ! 586: ! 587: /* Fill in the fields of the device structure with ethernet values. */ ! 588: ether_setup(dev); ! 589: ! 590: boot = 0; ! 591: ! 592: return 0; ! 593: } ! 594: ! 595: ! 596: static void eth16i_initialize(struct device *dev) ! 597: { ! 598: int ioaddr = dev->base_addr; ! 599: int i, node_w = 0; ! 600: unsigned char node_byte = 0; ! 601: ! 602: /* Setup station address */ ! 603: eth16i_select_regbank(NODE_ID_RB, ioaddr); ! 604: for(i = 0 ; i < 3 ; i++) { ! 605: unsigned short node_val = eth16i_read_eeprom(ioaddr, E_NODEID_0 + i); ! 606: ((unsigned short *)dev->dev_addr)[i] = ntohs(node_val); ! 607: } ! 608: ! 609: for(i = 0; i < 6; i++) { ! 610: outb( ((unsigned char *)dev->dev_addr)[i], ioaddr + NODE_ID_0 + i); ! 611: if(boot) { ! 612: printk("%02x", inb(ioaddr + NODE_ID_0 + i)); ! 613: if(i != 5) ! 614: printk(":"); ! 615: } ! 616: } ! 617: ! 618: /* Now we will set multicast addresses to accept none */ ! 619: eth16i_select_regbank(HASH_TABLE_RB, ioaddr); ! 620: for(i = 0; i < 8; i++) ! 621: outb(0x00, ioaddr + HASH_TABLE_0 + i); ! 622: ! 623: /* ! 624: Now let's disable the transmitter and receiver, set the buffer ram ! 625: cycle time, bus width and buffer data path width. Also we shall ! 626: set transmit buffer size and total buffer size. ! 627: */ ! 628: ! 629: eth16i_select_regbank(2, ioaddr); ! 630: ! 631: node_byte = 0; ! 632: node_w = eth16i_read_eeprom(ioaddr, E_PRODUCT_CFG); ! 633: ! 634: if( (node_w & 0xFF00) == 0x0800) ! 635: node_byte |= BUFFER_WIDTH_8; ! 636: ! 637: node_byte |= SRAM_BS1; ! 638: ! 639: if( (node_w & 0x00FF) == 64) ! 640: node_byte |= SRAM_BS0; ! 641: ! 642: node_byte |= DLC_EN | SRAM_CYCLE_TIME_100NS | (ETH16I_TX_BUF_SIZE << 2); ! 643: ! 644: outb(node_byte, ioaddr + CONFIG_REG_0); ! 645: ! 646: /* We shall halt the transmitting, if 16 collisions are detected */ ! 647: outb(HALT_ON_16, ioaddr + COL_16_REG); ! 648: ! 649: #ifdef MODULE ! 650: /* if_port already set by init_module() */ ! 651: #else ! 652: dev->if_port = (dev->mem_start < E_PORT_FROM_EPROM) ? ! 653: dev->mem_start : E_PORT_FROM_EPROM; ! 654: #endif ! 655: ! 656: /* Set interface port type */ ! 657: if(boot) { ! 658: char *porttype[] = {"BNC", "DIX", "TP", "AUTO", "FROM_EPROM" }; ! 659: ! 660: switch(dev->if_port) ! 661: { ! 662: ! 663: case E_PORT_FROM_EPROM: ! 664: dev->if_port = eth16i_read_eeprom(ioaddr, E_PORT_SELECT); ! 665: break; ! 666: ! 667: case E_PORT_AUTO: ! 668: dev->if_port = eth16i_probe_port(ioaddr); ! 669: break; ! 670: ! 671: case E_PORT_BNC: ! 672: case E_PORT_TP: ! 673: case E_PORT_DIX: ! 674: break; ! 675: } ! 676: ! 677: printk(" %s interface.\n", porttype[dev->if_port]); ! 678: ! 679: eth16i_set_port(ioaddr, dev->if_port); ! 680: } ! 681: ! 682: /* Set Receive Mode to normal operation */ ! 683: outb(MODE_2, ioaddr + RECEIVE_MODE_REG); ! 684: } ! 685: ! 686: static int eth16i_probe_port(int ioaddr) ! 687: { ! 688: int i; ! 689: int retcode; ! 690: unsigned char dummy_packet[64] = { 0 }; ! 691: ! 692: /* Powerup the chip */ ! 693: outb(0xc0 | POWERUP, ioaddr + CONFIG_REG_1); ! 694: ! 695: BITSET(ioaddr + CONFIG_REG_0, DLC_EN); ! 696: ! 697: eth16i_select_regbank(NODE_ID_RB, ioaddr); ! 698: ! 699: for(i = 0; i < 6; i++) { ! 700: dummy_packet[i] = inb(ioaddr + NODE_ID_0 + i); ! 701: dummy_packet[i+6] = inb(ioaddr + NODE_ID_0 + i); ! 702: } ! 703: ! 704: dummy_packet[12] = 0x00; ! 705: dummy_packet[13] = 0x04; ! 706: ! 707: eth16i_select_regbank(2, ioaddr); ! 708: ! 709: for(i = 0; i < 3; i++) { ! 710: BITSET(ioaddr + CONFIG_REG_0, DLC_EN); ! 711: BITCLR(ioaddr + CONFIG_REG_0, DLC_EN); ! 712: eth16i_set_port(ioaddr, i); ! 713: ! 714: if(eth16i_debug > 1) ! 715: printk(KERN_DEBUG "Set port number %d\n", i); ! 716: ! 717: retcode = eth16i_send_probe_packet(ioaddr, dummy_packet, 64); ! 718: if(retcode == 0) { ! 719: retcode = eth16i_receive_probe_packet(ioaddr); ! 720: if(retcode != -1) { ! 721: if(eth16i_debug > 1) ! 722: printk(KERN_DEBUG "Eth16i interface port found at %d\n", i); ! 723: return i; ! 724: } ! 725: } ! 726: else { ! 727: if(eth16i_debug > 1) ! 728: printk(KERN_DEBUG "TRANSMIT_DONE timeout when probing interface port\n"); ! 729: } ! 730: } ! 731: ! 732: if( eth16i_debug > 1) ! 733: printk(KERN_DEBUG "Using default port\n"); ! 734: ! 735: return E_PORT_BNC; ! 736: } ! 737: ! 738: static void eth16i_set_port(int ioaddr, int porttype) ! 739: { ! 740: unsigned short temp = 0; ! 741: ! 742: eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr); ! 743: outb(LOOPBACK_CONTROL, ioaddr + TRANSMIT_MODE_REG); ! 744: ! 745: temp |= DIS_AUTO_PORT_SEL; ! 746: ! 747: switch(porttype) { ! 748: ! 749: case E_PORT_BNC : ! 750: temp |= AUI_SELECT; ! 751: break; ! 752: ! 753: case E_PORT_TP : ! 754: break; ! 755: ! 756: case E_PORT_DIX : ! 757: temp |= AUI_SELECT; ! 758: BITSET(ioaddr + TRANSMIT_MODE_REG, CONTROL_OUTPUT); ! 759: break; ! 760: } ! 761: ! 762: outb(temp, ioaddr + TRANSCEIVER_MODE_REG); ! 763: ! 764: if(eth16i_debug > 1) { ! 765: printk(KERN_DEBUG "TRANSMIT_MODE_REG = %x\n", inb(ioaddr + TRANSMIT_MODE_REG)); ! 766: printk(KERN_DEBUG "TRANSCEIVER_MODE_REG = %x\n", ! 767: inb(ioaddr+TRANSCEIVER_MODE_REG)); ! 768: } ! 769: } ! 770: ! 771: static int eth16i_send_probe_packet(int ioaddr, unsigned char *b, int l) ! 772: { ! 773: int starttime; ! 774: ! 775: outb(0xff, ioaddr + TX_STATUS_REG); ! 776: ! 777: outw(l, ioaddr + DATAPORT); ! 778: outsw(ioaddr + DATAPORT, (unsigned short *)b, (l + 1) >> 1); ! 779: ! 780: starttime = jiffies; ! 781: outb(TX_START | 1, ioaddr + TRANSMIT_START_REG); ! 782: ! 783: while( (inb(ioaddr + TX_STATUS_REG) & 0x80) == 0) { ! 784: if( (jiffies - starttime) > TX_TIMEOUT) { ! 785: return -1; ! 786: } ! 787: } ! 788: ! 789: return 0; ! 790: } ! 791: ! 792: static int eth16i_receive_probe_packet(int ioaddr) ! 793: { ! 794: int starttime; ! 795: ! 796: starttime = jiffies; ! 797: ! 798: while((inb(ioaddr + TX_STATUS_REG) & 0x20) == 0) { ! 799: if( (jiffies - starttime) > TX_TIMEOUT) { ! 800: ! 801: if(eth16i_debug > 1) ! 802: printk(KERN_DEBUG "Timeout occured waiting transmit packet received\n"); ! 803: starttime = jiffies; ! 804: while((inb(ioaddr + RX_STATUS_REG) & 0x80) == 0) { ! 805: if( (jiffies - starttime) > TX_TIMEOUT) { ! 806: if(eth16i_debug > 1) ! 807: printk(KERN_DEBUG "Timeout occured waiting receive packet\n"); ! 808: return -1; ! 809: } ! 810: } ! 811: ! 812: if(eth16i_debug > 1) ! 813: printk(KERN_DEBUG "RECEIVE_PACKET\n"); ! 814: return(0); /* Found receive packet */ ! 815: } ! 816: } ! 817: ! 818: if(eth16i_debug > 1) { ! 819: printk(KERN_DEBUG "TRANSMIT_PACKET_RECEIVED %x\n", inb(ioaddr + TX_STATUS_REG)); ! 820: printk(KERN_DEBUG "RX_STATUS_REG = %x\n", inb(ioaddr + RX_STATUS_REG)); ! 821: } ! 822: ! 823: return(0); /* Return success */ ! 824: } ! 825: ! 826: #if 0 ! 827: static int eth16i_set_irq(struct device* dev) ! 828: { ! 829: const int ioaddr = dev->base_addr; ! 830: const int irq = dev->irq; ! 831: int i = 0; ! 832: ! 833: if(ioaddr < 0x1000) { ! 834: while(eth16i_irqmap[i] && eth16i_irqmap[i] != irq) ! 835: i++; ! 836: ! 837: if(i < NUM_OF_ISA_IRQS) { ! 838: u8 cbyte = inb(ioaddr + JUMPERLESS_CONFIG); ! 839: cbyte = (cbyte & 0x3F) | (i << 6); ! 840: outb(cbyte, ioaddr + JUMPERLESS_CONFIG); ! 841: return 0; ! 842: } ! 843: } ! 844: else { ! 845: printk(KERN_NOTICE "%s: EISA Interrupt cannot be set. Use EISA Configuration utility.\n", dev->name); ! 846: } ! 847: ! 848: return -1; ! 849: ! 850: } ! 851: #endif ! 852: ! 853: static int eth16i_get_irq(int ioaddr) ! 854: { ! 855: unsigned char cbyte; ! 856: ! 857: if( ioaddr < 0x1000) { ! 858: cbyte = inb(ioaddr + JUMPERLESS_CONFIG); ! 859: return( eth16i_irqmap[ ((cbyte & 0xC0) >> 6) ] ); ! 860: } else { /* Oh..the card is EISA so method getting IRQ different */ ! 861: unsigned short index = 0; ! 862: cbyte = inb(ioaddr + EISA_IRQ_REG); ! 863: while( (cbyte & 0x01) == 0) { ! 864: cbyte = cbyte >> 1; ! 865: index++; ! 866: } ! 867: return( eth32i_irqmap[ index ] ); ! 868: } ! 869: } ! 870: ! 871: static int eth16i_check_signature(int ioaddr) ! 872: { ! 873: int i; ! 874: unsigned char creg[4] = { 0 }; ! 875: ! 876: for(i = 0; i < 4 ; i++) { ! 877: ! 878: creg[i] = inb(ioaddr + TRANSMIT_MODE_REG + i); ! 879: ! 880: if(eth16i_debug > 1) ! 881: printk("eth16i: read signature byte %x at %x\n", ! 882: creg[i], ! 883: ioaddr + TRANSMIT_MODE_REG + i); ! 884: } ! 885: ! 886: creg[0] &= 0x0F; /* Mask collision cnr */ ! 887: creg[2] &= 0x7F; /* Mask DCLEN bit */ ! 888: ! 889: #ifdef 0 ! 890: /* ! 891: This was removed because the card was sometimes left to state ! 892: from which it couldn't be find anymore. If there is need ! 893: to more strict check still this have to be fixed. ! 894: */ ! 895: if( ! ((creg[0] == 0x06) && (creg[1] == 0x41)) ) { ! 896: if(creg[1] != 0x42) ! 897: return -1; ! 898: } ! 899: #endif ! 900: ! 901: if( !((creg[2] == 0x36) && (creg[3] == 0xE0)) ) { ! 902: creg[2] &= 0x40; ! 903: creg[3] &= 0x03; ! 904: ! 905: if( !((creg[2] == 0x40) && (creg[3] == 0x00)) ) ! 906: return -1; ! 907: } ! 908: ! 909: if(eth16i_read_eeprom(ioaddr, E_NODEID_0) != 0) ! 910: return -1; ! 911: ! 912: if((eth16i_read_eeprom(ioaddr, E_NODEID_1) & 0xFF00) != 0x4B00) ! 913: return -1; ! 914: ! 915: return 0; ! 916: } ! 917: ! 918: static int eth16i_read_eeprom(int ioaddr, int offset) ! 919: { ! 920: int data = 0; ! 921: ! 922: eth16i_eeprom_cmd(ioaddr, EEPROM_READ | offset); ! 923: outb(CS_1, ioaddr + EEPROM_CTRL_REG); ! 924: data = eth16i_read_eeprom_word(ioaddr); ! 925: outb(CS_0 | SK_0, ioaddr + EEPROM_CTRL_REG); ! 926: ! 927: return(data); ! 928: } ! 929: ! 930: static int eth16i_read_eeprom_word(int ioaddr) ! 931: { ! 932: int i; ! 933: int data = 0; ! 934: ! 935: for(i = 16; i > 0; i--) { ! 936: outb(CS_1 | SK_0, ioaddr + EEPROM_CTRL_REG); ! 937: eeprom_slow_io(); ! 938: outb(CS_1 | SK_1, ioaddr + EEPROM_CTRL_REG); ! 939: eeprom_slow_io(); ! 940: data = (data << 1) | ! 941: ((inb(ioaddr + EEPROM_DATA_REG) & DI_1) ? 1 : 0); ! 942: ! 943: eeprom_slow_io(); ! 944: } ! 945: ! 946: return(data); ! 947: } ! 948: ! 949: static void eth16i_eeprom_cmd(int ioaddr, unsigned char command) ! 950: { ! 951: int i; ! 952: ! 953: outb(CS_0 | SK_0, ioaddr + EEPROM_CTRL_REG); ! 954: outb(DI_0, ioaddr + EEPROM_DATA_REG); ! 955: outb(CS_1 | SK_0, ioaddr + EEPROM_CTRL_REG); ! 956: outb(DI_1, ioaddr + EEPROM_DATA_REG); ! 957: outb(CS_1 | SK_1, ioaddr + EEPROM_CTRL_REG); ! 958: ! 959: for(i = 7; i >= 0; i--) { ! 960: short cmd = ( (command & (1 << i)) ? DI_1 : DI_0 ); ! 961: outb(cmd, ioaddr + EEPROM_DATA_REG); ! 962: outb(CS_1 | SK_0, ioaddr + EEPROM_CTRL_REG); ! 963: eeprom_slow_io(); ! 964: outb(CS_1 | SK_1, ioaddr + EEPROM_CTRL_REG); ! 965: eeprom_slow_io(); ! 966: } ! 967: } ! 968: ! 969: static int eth16i_open(struct device *dev) ! 970: { ! 971: struct eth16i_local *lp = (struct eth16i_local *)dev->priv; ! 972: int ioaddr = dev->base_addr; ! 973: ! 974: /* Powerup the chip */ ! 975: outb(0xc0 | POWERUP, ioaddr + CONFIG_REG_1); ! 976: ! 977: /* Initialize the chip */ ! 978: eth16i_initialize(dev); ! 979: ! 980: /* Set the transmit buffer size */ ! 981: lp->tx_buf_size = eth16i_tx_buf_map[ETH16I_TX_BUF_SIZE & 0x03]; ! 982: ! 983: if(eth16i_debug > 0) ! 984: printk(KERN_DEBUG "%s: transmit buffer size %d\n", ! 985: dev->name, lp->tx_buf_size); ! 986: ! 987: /* Now enable Transmitter and Receiver sections */ ! 988: BITCLR(ioaddr + CONFIG_REG_0, DLC_EN); ! 989: ! 990: /* Now switch to register bank 2, for run time operation */ ! 991: eth16i_select_regbank(2, ioaddr); ! 992: ! 993: lp->open_time = jiffies; ! 994: lp->tx_started = 0; ! 995: lp->tx_queue = 0; ! 996: lp->tx_queue_len = 0; ! 997: ! 998: /* Turn on interrupts*/ ! 999: outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG); ! 1000: ! 1001: dev->tbusy = 0; ! 1002: dev->interrupt = 0; ! 1003: dev->start = 1; ! 1004: ! 1005: MOD_INC_USE_COUNT; ! 1006: ! 1007: return 0; ! 1008: } ! 1009: ! 1010: static int eth16i_close(struct device *dev) ! 1011: { ! 1012: struct eth16i_local *lp = (struct eth16i_local *)dev->priv; ! 1013: int ioaddr = dev->base_addr; ! 1014: ! 1015: eth16i_reset(dev); ! 1016: ! 1017: /* Turn off interrupts*/ ! 1018: outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG); ! 1019: ! 1020: dev->start = 0; ! 1021: dev->tbusy = 1; ! 1022: ! 1023: lp->open_time = 0; ! 1024: ! 1025: /* Disable transmit and receive */ ! 1026: BITSET(ioaddr + CONFIG_REG_0, DLC_EN); ! 1027: ! 1028: /* Reset the chip */ ! 1029: /* outb(0xff, ioaddr + RESET); */ ! 1030: /* outw(0xffff, ioaddr + TX_STATUS_REG); */ ! 1031: ! 1032: outb(0x00, ioaddr + CONFIG_REG_1); ! 1033: ! 1034: MOD_DEC_USE_COUNT; ! 1035: ! 1036: return 0; ! 1037: } ! 1038: ! 1039: static int eth16i_tx(struct sk_buff *skb, struct device *dev) ! 1040: { ! 1041: struct eth16i_local *lp = (struct eth16i_local *)dev->priv; ! 1042: int ioaddr = dev->base_addr; ! 1043: int status = 0; ! 1044: ! 1045: if(dev->tbusy) { ! 1046: ! 1047: /* ! 1048: If we get here, some higher level has decided that ! 1049: we are broken. There should really be a "kick me" ! 1050: function call instead. ! 1051: */ ! 1052: ! 1053: int tickssofar = jiffies - dev->trans_start; ! 1054: if(tickssofar < TX_TIMEOUT) ! 1055: return 1; ! 1056: ! 1057: outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG); ! 1058: ! 1059: printk(KERN_WARNING "%s: transmit timed out with status %04x, %s ?\n", ! 1060: dev->name, ! 1061: inw(ioaddr + TX_STATUS_REG), ! 1062: (inb(ioaddr + TX_STATUS_REG) & TX_DONE) ? ! 1063: "IRQ conflict" : "network cable problem"); ! 1064: ! 1065: dev->trans_start = jiffies; ! 1066: ! 1067: /* Let's dump all registers */ ! 1068: if(eth16i_debug > 0) { ! 1069: printk(KERN_DEBUG "%s: timeout: %02x %02x %02x %02x %02x %02x %02x %02x.\n", ! 1070: dev->name, inb(ioaddr + 0), ! 1071: inb(ioaddr + 1), inb(ioaddr + 2), ! 1072: inb(ioaddr + 3), inb(ioaddr + 4), ! 1073: inb(ioaddr + 5), ! 1074: inb(ioaddr + 6), inb(ioaddr + 7)); ! 1075: ! 1076: printk(KERN_DEBUG "%s: transmit start reg: %02x. collision reg %02x\n", ! 1077: dev->name, inb(ioaddr + TRANSMIT_START_REG), ! 1078: inb(ioaddr + COL_16_REG)); ! 1079: ! 1080: printk(KERN_DEBUG "lp->tx_queue = %d\n", lp->tx_queue); ! 1081: printk(KERN_DEBUG "lp->tx_queue_len = %d\n", lp->tx_queue_len); ! 1082: printk(KERN_DEBUG "lp->tx_started = %d\n", lp->tx_started); ! 1083: ! 1084: } ! 1085: ! 1086: lp->stats.tx_errors++; ! 1087: ! 1088: eth16i_reset(dev); ! 1089: ! 1090: dev->trans_start = jiffies; ! 1091: ! 1092: outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG); ! 1093: ! 1094: } ! 1095: ! 1096: /* ! 1097: If some higher layer thinks we've missed an tx-done interrupt ! 1098: we are passed NULL. Caution: dev_tint() handles the cli()/sti() ! 1099: itself ! 1100: */ ! 1101: ! 1102: if(skb == NULL) { ! 1103: #if LINUX_VERSION_CODE < 0x020100 ! 1104: dev_tint(dev); ! 1105: #endif ! 1106: if(eth16i_debug > 0) ! 1107: printk(KERN_WARNING "%s: Missed tx-done interrupt.\n", dev->name); ! 1108: return 0; ! 1109: } ! 1110: ! 1111: /* Block a timer based transmitter from overlapping. ! 1112: This could better be done with atomic_swap(1, dev->tbusy), ! 1113: but set_bit() works as well. */ ! 1114: ! 1115: set_bit(0, (void *)&lp->tx_buf_busy); ! 1116: ! 1117: /* Turn off TX interrupts */ ! 1118: outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG); ! 1119: ! 1120: if(test_and_set_bit(0, (void *)&dev->tbusy) != 0) { ! 1121: printk(KERN_WARNING "%s: Transmitter access conflict.\n", dev->name); ! 1122: status = -1; ! 1123: } ! 1124: else { ! 1125: ushort length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; ! 1126: unsigned char *buf = skb->data; ! 1127: ! 1128: if( (length + 2) > (lp->tx_buf_size - lp->tx_queue_len)) { ! 1129: if(eth16i_debug > 0) ! 1130: printk(KERN_WARNING "%s: Transmit buffer full.\n", dev->name); ! 1131: } ! 1132: else { ! 1133: outw(length, ioaddr + DATAPORT); ! 1134: ! 1135: if( ioaddr < 0x1000 ) ! 1136: outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1); ! 1137: else { ! 1138: unsigned char frag = length % 4; ! 1139: ! 1140: outsl(ioaddr + DATAPORT, buf, length >> 2); ! 1141: ! 1142: if( frag != 0 ) { ! 1143: outsw(ioaddr + DATAPORT, (buf + (length & 0xFFFC)), 1); ! 1144: if( frag == 3 ) ! 1145: outsw(ioaddr + DATAPORT, ! 1146: (buf + (length & 0xFFFC) + 2), 1); ! 1147: } ! 1148: } ! 1149: ! 1150: lp->tx_buffered_packets++; ! 1151: lp->tx_queue++; ! 1152: lp->tx_queue_len += length + 2; ! 1153: ! 1154: } ! 1155: ! 1156: lp->tx_buf_busy = 0; ! 1157: ! 1158: if(lp->tx_started == 0) { ! 1159: /* If the transmitter is idle..always trigger a transmit */ ! 1160: outb(TX_START | lp->tx_queue, ioaddr + TRANSMIT_START_REG); ! 1161: lp->tx_queue = 0; ! 1162: lp->tx_queue_len = 0; ! 1163: dev->trans_start = jiffies; ! 1164: lp->tx_started = 1; ! 1165: dev->tbusy = 0; ! 1166: } ! 1167: else if(lp->tx_queue_len < lp->tx_buf_size - (ETH_FRAME_LEN + 2)) { ! 1168: /* There is still more room for one more packet in tx buffer */ ! 1169: dev->tbusy = 0; ! 1170: } ! 1171: ! 1172: outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG); ! 1173: ! 1174: /* Turn TX interrupts back on */ ! 1175: /* outb(TX_INTR_DONE | TX_INTR_16_COL, ioaddr + TX_INTR_REG); */ ! 1176: status = 0; ! 1177: } ! 1178: ! 1179: #if LINUX_VERSION_CODE >= 0x020100 ! 1180: dev_kfree_skb(skb); ! 1181: #else ! 1182: dev_kfree_skb(skb, FREE_WRITE); ! 1183: #endif ! 1184: ! 1185: return status; ! 1186: } ! 1187: ! 1188: static void eth16i_rx(struct device *dev) ! 1189: { ! 1190: struct eth16i_local *lp = (struct eth16i_local *)dev->priv; ! 1191: int ioaddr = dev->base_addr; ! 1192: int boguscount = MAX_RX_LOOP; ! 1193: ! 1194: /* Loop until all packets have been read */ ! 1195: while( (inb(ioaddr + RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 0) { ! 1196: ! 1197: /* Read status byte from receive buffer */ ! 1198: ushort status = inw(ioaddr + DATAPORT); ! 1199: ! 1200: /* Get the size of the packet from receive buffer */ ! 1201: ushort pkt_len = inw(ioaddr + DATAPORT); ! 1202: ! 1203: if(eth16i_debug > 4) ! 1204: printk(KERN_DEBUG "%s: Receiving packet mode %02x status %04x.\n", ! 1205: dev->name, ! 1206: inb(ioaddr + RECEIVE_MODE_REG), status); ! 1207: ! 1208: if( !(status & PKT_GOOD) ) { ! 1209: lp->stats.rx_errors++; ! 1210: ! 1211: if( (pkt_len < ETH_ZLEN) || (pkt_len > ETH_FRAME_LEN) ) { ! 1212: lp->stats.rx_length_errors++; ! 1213: eth16i_reset(dev); ! 1214: return; ! 1215: } ! 1216: else { ! 1217: eth16i_skip_packet(dev); ! 1218: lp->stats.rx_dropped++; ! 1219: } ! 1220: } ! 1221: else { /* Ok so now we should have a good packet */ ! 1222: struct sk_buff *skb; ! 1223: ! 1224: skb = dev_alloc_skb(pkt_len + 3); ! 1225: if( skb == NULL ) { ! 1226: printk(KERN_WARNING "%s: Could'n allocate memory for packet (len %d)\n", ! 1227: dev->name, pkt_len); ! 1228: eth16i_skip_packet(dev); ! 1229: lp->stats.rx_dropped++; ! 1230: break; ! 1231: } ! 1232: ! 1233: skb->dev = dev; ! 1234: skb_reserve(skb,2); ! 1235: ! 1236: /* ! 1237: Now let's get the packet out of buffer. ! 1238: size is (pkt_len + 1) >> 1, cause we are now reading words ! 1239: and it have to be even aligned. ! 1240: */ ! 1241: ! 1242: if(ioaddr < 0x1000) ! 1243: insw(ioaddr + DATAPORT, skb_put(skb, pkt_len), ! 1244: (pkt_len + 1) >> 1); ! 1245: else { ! 1246: unsigned char *buf = skb_put(skb, pkt_len); ! 1247: unsigned char frag = pkt_len % 4; ! 1248: ! 1249: insl(ioaddr + DATAPORT, buf, pkt_len >> 2); ! 1250: ! 1251: if(frag != 0) { ! 1252: unsigned short rest[2]; ! 1253: rest[0] = inw( ioaddr + DATAPORT ); ! 1254: if(frag == 3) ! 1255: rest[1] = inw( ioaddr + DATAPORT ); ! 1256: ! 1257: memcpy(buf + (pkt_len & 0xfffc), (char *)rest, frag); ! 1258: } ! 1259: } ! 1260: ! 1261: skb->protocol=eth_type_trans(skb, dev); ! 1262: netif_rx(skb); ! 1263: lp->stats.rx_packets++; ! 1264: ! 1265: if( eth16i_debug > 5 ) { ! 1266: int i; ! 1267: printk(KERN_DEBUG "%s: Received packet of length %d.\n", ! 1268: dev->name, pkt_len); ! 1269: for(i = 0; i < 14; i++) ! 1270: printk(KERN_DEBUG " %02x", skb->data[i]); ! 1271: printk(KERN_DEBUG ".\n"); ! 1272: } ! 1273: ! 1274: } /* else */ ! 1275: ! 1276: if(--boguscount <= 0) ! 1277: break; ! 1278: ! 1279: } /* while */ ! 1280: ! 1281: #if 0 ! 1282: { ! 1283: int i; ! 1284: ! 1285: for(i = 0; i < 20; i++) { ! 1286: if( (inb(ioaddr+RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == ! 1287: RX_BUFFER_EMPTY) ! 1288: break; ! 1289: inw(ioaddr + DATAPORT); ! 1290: outb(SKIP_RX_PACKET, ioaddr + FILTER_SELF_RX_REG); ! 1291: } ! 1292: ! 1293: if(eth16i_debug > 1) ! 1294: printk(KERN_DEBUG "%s: Flushed receive buffer.\n", dev->name); ! 1295: } ! 1296: #endif ! 1297: ! 1298: return; ! 1299: } ! 1300: ! 1301: static void eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs) ! 1302: { ! 1303: struct device *dev = dev_id; ! 1304: struct eth16i_local *lp; ! 1305: int ioaddr = 0, ! 1306: status; ! 1307: ! 1308: if(dev == NULL) { ! 1309: printk(KERN_WARNING "eth16i_interrupt(): irq %d for unknown device. \n", irq); ! 1310: return; ! 1311: } ! 1312: ! 1313: /* Turn off all interrupts from adapter */ ! 1314: outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG); ! 1315: ! 1316: set_bit(0, (void *)&dev->tbusy); /* Set the device busy so that */ ! 1317: /* eth16i_tx wont be called */ ! 1318: ! 1319: if(dev->interrupt) ! 1320: printk(KERN_WARNING "%s: Re-entering the interrupt handler.\n", dev->name); ! 1321: dev->interrupt = 1; ! 1322: ! 1323: ioaddr = dev->base_addr; ! 1324: lp = (struct eth16i_local *)dev->priv; ! 1325: status = inw(ioaddr + TX_STATUS_REG); /* Get the status */ ! 1326: outw(status, ioaddr + TX_STATUS_REG); /* Clear status bits */ ! 1327: ! 1328: if(eth16i_debug > 3) ! 1329: printk(KERN_DEBUG "%s: Interrupt with status %04x.\n", dev->name, status); ! 1330: ! 1331: if( status & 0x7f00 ) { ! 1332: ! 1333: lp->stats.rx_errors++; ! 1334: ! 1335: if(status & (BUS_RD_ERR << 8) ) ! 1336: printk(KERN_WARNING "%s: Bus read error.\n",dev->name); ! 1337: if(status & (SHORT_PKT_ERR << 8) ) lp->stats.rx_length_errors++; ! 1338: if(status & (ALIGN_ERR << 8) ) lp->stats.rx_frame_errors++; ! 1339: if(status & (CRC_ERR << 8) ) lp->stats.rx_crc_errors++; ! 1340: if(status & (RX_BUF_OVERFLOW << 8) ) lp->stats.rx_over_errors++; ! 1341: } ! 1342: if( status & 0x001a) { ! 1343: ! 1344: lp->stats.tx_errors++; ! 1345: ! 1346: if(status & CR_LOST) lp->stats.tx_carrier_errors++; ! 1347: if(status & TX_JABBER_ERR) lp->stats.tx_window_errors++; ! 1348: ! 1349: #if 0 ! 1350: if(status & COLLISION) { ! 1351: lp->stats.collisions += ! 1352: ((inb(ioaddr+TRANSMIT_MODE_REG) & 0xF0) >> 4); ! 1353: } ! 1354: #endif ! 1355: if(status & COLLISIONS_16) { ! 1356: if(lp->col_16 < MAX_COL_16) { ! 1357: lp->col_16++; ! 1358: lp->stats.collisions++; ! 1359: /* Resume transmitting, skip failed packet */ ! 1360: outb(0x02, ioaddr + COL_16_REG); ! 1361: } ! 1362: else { ! 1363: printk(KERN_WARNING "%s: bailing out due to many consecutive 16-in-a-row collisions. Network cable problem?\n", dev->name); ! 1364: } ! 1365: } ! 1366: } ! 1367: ! 1368: if( status & 0x00ff ) { /* Let's check the transmit status reg */ ! 1369: ! 1370: if(status & TX_DONE) { /* The transmit has been done */ ! 1371: lp->stats.tx_packets = lp->tx_buffered_packets; ! 1372: lp->col_16 = 0; ! 1373: ! 1374: if(lp->tx_queue) { /* Is there still packets ? */ ! 1375: /* There was packet(s) so start transmitting and write also ! 1376: how many packets there is to be sended */ ! 1377: outb(TX_START | lp->tx_queue, ioaddr + TRANSMIT_START_REG); ! 1378: lp->tx_queue = 0; ! 1379: lp->tx_queue_len = 0; ! 1380: lp->tx_started = 1; ! 1381: dev->trans_start = jiffies; ! 1382: mark_bh(NET_BH); ! 1383: } ! 1384: else { ! 1385: lp->tx_started = 0; ! 1386: mark_bh(NET_BH); ! 1387: } ! 1388: } ! 1389: } ! 1390: ! 1391: if( ( status & 0x8000 ) || ! 1392: ( (inb(ioaddr + RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 0) ) { ! 1393: eth16i_rx(dev); /* We have packet in receive buffer */ ! 1394: } ! 1395: ! 1396: dev->interrupt = 0; ! 1397: ! 1398: /* Turn interrupts back on */ ! 1399: outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG); ! 1400: ! 1401: if(lp->tx_queue_len < lp->tx_buf_size - (ETH_FRAME_LEN + 2)) { ! 1402: /* There is still more room for one more packet in tx buffer */ ! 1403: dev->tbusy = 0; ! 1404: } ! 1405: ! 1406: return; ! 1407: } ! 1408: ! 1409: static void eth16i_skip_packet(struct device *dev) ! 1410: { ! 1411: int ioaddr = dev->base_addr; ! 1412: ! 1413: inw(ioaddr + DATAPORT); ! 1414: inw(ioaddr + DATAPORT); ! 1415: inw(ioaddr + DATAPORT); ! 1416: ! 1417: outb(SKIP_RX_PACKET, ioaddr + FILTER_SELF_RX_REG); ! 1418: while( inb( ioaddr + FILTER_SELF_RX_REG ) != 0); ! 1419: } ! 1420: ! 1421: static void eth16i_reset(struct device *dev) ! 1422: { ! 1423: struct eth16i_local *lp = (struct eth16i_local *)dev->priv; ! 1424: int ioaddr = dev->base_addr; ! 1425: ! 1426: if(eth16i_debug > 1) ! 1427: printk(KERN_DEBUG "%s: Resetting device.\n", dev->name); ! 1428: ! 1429: BITSET(ioaddr + CONFIG_REG_0, DLC_EN); ! 1430: outw(0xffff, ioaddr + TX_STATUS_REG); ! 1431: eth16i_select_regbank(2, ioaddr); ! 1432: ! 1433: lp->tx_started = 0; ! 1434: lp->tx_buf_busy = 0; ! 1435: lp->tx_queue = 0; ! 1436: lp->tx_queue_len = 0; ! 1437: ! 1438: dev->interrupt = 0; ! 1439: dev->start = 1; ! 1440: dev->tbusy = 0; ! 1441: BITCLR(ioaddr + CONFIG_REG_0, DLC_EN); ! 1442: } ! 1443: ! 1444: static void eth16i_multicast(struct device *dev) ! 1445: { ! 1446: int ioaddr = dev->base_addr; ! 1447: ! 1448: if(dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC)) ! 1449: { ! 1450: dev->flags|=IFF_PROMISC; /* Must do this */ ! 1451: outb(3, ioaddr + RECEIVE_MODE_REG); ! 1452: } else { ! 1453: outb(2, ioaddr + RECEIVE_MODE_REG); ! 1454: } ! 1455: } ! 1456: ! 1457: static struct enet_statistics *eth16i_get_stats(struct device *dev) ! 1458: { ! 1459: struct eth16i_local *lp = (struct eth16i_local *)dev->priv; ! 1460: ! 1461: return &lp->stats; ! 1462: } ! 1463: ! 1464: static void eth16i_select_regbank(unsigned char banknbr, int ioaddr) ! 1465: { ! 1466: unsigned char data; ! 1467: ! 1468: data = inb(ioaddr + CONFIG_REG_1); ! 1469: outb( ((data & 0xF3) | ( (banknbr & 0x03) << 2)), ioaddr + CONFIG_REG_1); ! 1470: } ! 1471: ! 1472: #ifdef MODULE ! 1473: ! 1474: static ushort eth16i_parse_mediatype(const char* s) ! 1475: { ! 1476: if(!s) ! 1477: return E_PORT_FROM_EPROM; ! 1478: ! 1479: if (!strncmp(s, "bnc", 3)) ! 1480: return E_PORT_BNC; ! 1481: else if (!strncmp(s, "tp", 2)) ! 1482: return E_PORT_TP; ! 1483: else if (!strncmp(s, "dix", 3)) ! 1484: return E_PORT_DIX; ! 1485: else if (!strncmp(s, "auto", 4)) ! 1486: return E_PORT_AUTO; ! 1487: else ! 1488: return E_PORT_FROM_EPROM; ! 1489: } ! 1490: ! 1491: #define MAX_ETH16I_CARDS 4 /* Max number of Eth16i cards per module */ ! 1492: #define NAMELEN 8 /* number of chars for storing dev->name */ ! 1493: ! 1494: static char namelist[NAMELEN * MAX_ETH16I_CARDS] = { 0, }; ! 1495: static struct device dev_eth16i[MAX_ETH16I_CARDS] = { ! 1496: { ! 1497: NULL, ! 1498: 0, 0, 0, 0, ! 1499: 0, 0, ! 1500: 0, 0, 0, NULL, NULL ! 1501: }, ! 1502: }; ! 1503: ! 1504: static int ioaddr[MAX_ETH16I_CARDS] = { 0, }; ! 1505: #if 0 ! 1506: static int irq[MAX_ETH16I_CARDS] = { 0, }; ! 1507: #endif ! 1508: static char* mediatype[MAX_ETH16I_CARDS] = { 0, }; ! 1509: static int debug = -1; ! 1510: ! 1511: #if (LINUX_VERSION_CODE >= 0x20115) ! 1512: MODULE_AUTHOR("Mika Kuoppala <[email protected]>"); ! 1513: MODULE_DESCRIPTION("ICL EtherTeam 16i/32 driver"); ! 1514: ! 1515: MODULE_PARM(ioaddr, "1-" __MODULE_STRING(MAX_ETH16I_CARDS) "i"); ! 1516: MODULE_PARM_DESC(ioaddr, "eth16i io base address"); ! 1517: ! 1518: #if 0 ! 1519: MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_ETH16I_CARDS) "i"); ! 1520: MODULE_PARM_DESC(irq, "eth16i interrupt request number"); ! 1521: #endif ! 1522: ! 1523: MODULE_PARM(mediatype, "1-" __MODULE_STRING(MAX_ETH16I_CARDS) "s"); ! 1524: MODULE_PARM_DESC(mediatype, "eth16i interfaceport mediatype"); ! 1525: ! 1526: MODULE_PARM(debug, "i"); ! 1527: MODULE_PARM_DESC(debug, "eth16i debug level (0-4)"); ! 1528: #endif ! 1529: ! 1530: int init_module(void) ! 1531: { ! 1532: int this_dev, found = 0; ! 1533: ! 1534: for(this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++) ! 1535: { ! 1536: struct device *dev = &dev_eth16i[this_dev]; ! 1537: ! 1538: dev->name = namelist + (NAMELEN*this_dev); ! 1539: dev->irq = 0; /* irq[this_dev]; */ ! 1540: dev->base_addr = ioaddr[this_dev]; ! 1541: dev->init = eth16i_probe; ! 1542: ! 1543: if(debug != -1) ! 1544: eth16i_debug = debug; ! 1545: ! 1546: if(eth16i_debug > 1) ! 1547: printk(KERN_NOTICE "eth16i(%d): interface type %s\n", this_dev, mediatype[this_dev] ? mediatype[this_dev] : "none" ); ! 1548: ! 1549: dev->if_port = eth16i_parse_mediatype(mediatype[this_dev]); ! 1550: ! 1551: if(ioaddr[this_dev] == 0) ! 1552: { ! 1553: if(this_dev != 0) break; /* Only autoprobe 1st one */ ! 1554: ! 1555: printk(KERN_NOTICE "eth16i.c: Presently autoprobing (not recommended) for a single card.\n"); ! 1556: } ! 1557: ! 1558: if(register_netdev(dev) != 0) ! 1559: { ! 1560: printk(KERN_WARNING "eth16i.c No Eth16i card found (i/o = 0x%x).\n", ! 1561: ioaddr[this_dev]); ! 1562: ! 1563: if(found != 0) return 0; ! 1564: return -ENXIO; ! 1565: } ! 1566: ! 1567: found++; ! 1568: } ! 1569: return 0; ! 1570: } ! 1571: ! 1572: void cleanup_module(void) ! 1573: { ! 1574: int this_dev; ! 1575: ! 1576: for(this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++) ! 1577: { ! 1578: struct device* dev = &dev_eth16i[this_dev]; ! 1579: ! 1580: if(dev->priv != NULL) ! 1581: { ! 1582: unregister_netdev(dev); ! 1583: kfree(dev->priv); ! 1584: dev->priv = NULL; ! 1585: ! 1586: free_irq(dev->irq, dev); ! 1587: release_region(dev->base_addr, ETH16I_IO_EXTENT); ! 1588: ! 1589: } ! 1590: } ! 1591: } ! 1592: #endif /* MODULE */ ! 1593: ! 1594: /* ! 1595: * Local variables: ! 1596: * compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c eth16i.c" ! 1597: * alt-compile-command: "gcc -DMODVERSIONS -DMODULE -D__KERNEL__ -Wall -Wstrict -prototypes -O6 -c eth16i.c" ! 1598: * tab-width: 8 ! 1599: * c-basic-offset: 8 ! 1600: * c-indent-level: 8 ! 1601: * End: ! 1602: */ ! 1603: ! 1604: /* End of file eth16i.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.