|
|
1.1 ! root 1: #ifdef ALLMULTI ! 2: #error multicast support is not yet implemented ! 3: #endif ! 4: /************************************************************************** ! 5: Etherboot - BOOTP/TFTP Bootstrap Program ! 6: Intel EEPRO/10 NIC driver for Etherboot ! 7: Adapted from Linux eepro.c from kernel 2.2.17 ! 8: ! 9: This board accepts a 32 pin EEPROM (29C256), however a test with a ! 10: 27C010 shows that this EPROM also works in the socket, but it's not clear ! 11: how repeatably. The two top address pins appear to be held low, thus ! 12: the bottom 32kB of the 27C010 is visible in the CPU's address space. ! 13: To be sure you could put 4 copies of the code in the 27C010, then ! 14: it doesn't matter whether the extra lines are held low or high, just ! 15: hopefully not floating as CMOS chips don't like floating inputs. ! 16: ! 17: Be careful with seating the EPROM as the socket on my board actually ! 18: has 34 pins, the top row of 2 are not used. ! 19: ***************************************************************************/ ! 20: ! 21: /* ! 22: ! 23: timlegge 2005-05-18 remove the relocation changes cards that ! 24: write directly to the hardware don't need it ! 25: */ ! 26: ! 27: /* ! 28: * This program is free software; you can redistribute it and/or ! 29: * modify it under the terms of the GNU General Public License as ! 30: * published by the Free Software Foundation; either version 2, or (at ! 31: * your option) any later version. ! 32: */ ! 33: ! 34: FILE_LICENCE ( GPL2_OR_LATER ); ! 35: ! 36: #include "etherboot.h" ! 37: #include <errno.h> ! 38: #include "nic.h" ! 39: #include <ipxe/isa.h> ! 40: #include <ipxe/ethernet.h> ! 41: ! 42: /* Different 82595 chips */ ! 43: #define LAN595 0 ! 44: #define LAN595TX 1 ! 45: #define LAN595FX 2 ! 46: #define LAN595FX_10ISA 3 ! 47: ! 48: #define SLOW_DOWN inb(0x80); ! 49: ! 50: /* The station (ethernet) address prefix, used for IDing the board. */ ! 51: #define SA_ADDR0 0x00 /* Etherexpress Pro/10 */ ! 52: #define SA_ADDR1 0xaa ! 53: #define SA_ADDR2 0x00 ! 54: ! 55: #define GetBit(x,y) ((x & (1<<y))>>y) ! 56: ! 57: /* EEPROM Word 0: */ ! 58: #define ee_PnP 0 /* Plug 'n Play enable bit */ ! 59: #define ee_Word1 1 /* Word 1? */ ! 60: #define ee_BusWidth 2 /* 8/16 bit */ ! 61: #define ee_FlashAddr 3 /* Flash Address */ ! 62: #define ee_FlashMask 0x7 /* Mask */ ! 63: #define ee_AutoIO 6 /* */ ! 64: #define ee_reserved0 7 /* =0! */ ! 65: #define ee_Flash 8 /* Flash there? */ ! 66: #define ee_AutoNeg 9 /* Auto Negotiation enabled? */ ! 67: #define ee_IO0 10 /* IO Address LSB */ ! 68: #define ee_IO0Mask 0x /*...*/ ! 69: #define ee_IO1 15 /* IO MSB */ ! 70: ! 71: /* EEPROM Word 1: */ ! 72: #define ee_IntSel 0 /* Interrupt */ ! 73: #define ee_IntMask 0x7 ! 74: #define ee_LI 3 /* Link Integrity 0= enabled */ ! 75: #define ee_PC 4 /* Polarity Correction 0= enabled */ ! 76: #define ee_TPE_AUI 5 /* PortSelection 1=TPE */ ! 77: #define ee_Jabber 6 /* Jabber prevention 0= enabled */ ! 78: #define ee_AutoPort 7 /* Auto Port Selection 1= Disabled */ ! 79: #define ee_SMOUT 8 /* SMout Pin Control 0= Input */ ! 80: #define ee_PROM 9 /* Flash EPROM / PROM 0=Flash */ ! 81: #define ee_reserved1 10 /* .. 12 =0! */ ! 82: #define ee_AltReady 13 /* Alternate Ready, 0=normal */ ! 83: #define ee_reserved2 14 /* =0! */ ! 84: #define ee_Duplex 15 ! 85: ! 86: /* Word2,3,4: */ ! 87: #define ee_IA5 0 /*bit start for individual Addr Byte 5 */ ! 88: #define ee_IA4 8 /*bit start for individual Addr Byte 5 */ ! 89: #define ee_IA3 0 /*bit start for individual Addr Byte 5 */ ! 90: #define ee_IA2 8 /*bit start for individual Addr Byte 5 */ ! 91: #define ee_IA1 0 /*bit start for individual Addr Byte 5 */ ! 92: #define ee_IA0 8 /*bit start for individual Addr Byte 5 */ ! 93: ! 94: /* Word 5: */ ! 95: #define ee_BNC_TPE 0 /* 0=TPE */ ! 96: #define ee_BootType 1 /* 00=None, 01=IPX, 10=ODI, 11=NDIS */ ! 97: #define ee_BootTypeMask 0x3 ! 98: #define ee_NumConn 3 /* Number of Connections 0= One or Two */ ! 99: #define ee_FlashSock 4 /* Presence of Flash Socket 0= Present */ ! 100: #define ee_PortTPE 5 ! 101: #define ee_PortBNC 6 ! 102: #define ee_PortAUI 7 ! 103: #define ee_PowerMgt 10 /* 0= disabled */ ! 104: #define ee_CP 13 /* Concurrent Processing */ ! 105: #define ee_CPMask 0x7 ! 106: ! 107: /* Word 6: */ ! 108: #define ee_Stepping 0 /* Stepping info */ ! 109: #define ee_StepMask 0x0F ! 110: #define ee_BoardID 4 /* Manucaturer Board ID, reserved */ ! 111: #define ee_BoardMask 0x0FFF ! 112: ! 113: /* Word 7: */ ! 114: #define ee_INT_TO_IRQ 0 /* int to IRQ Mapping = 0x1EB8 for Pro/10+ */ ! 115: #define ee_FX_INT2IRQ 0x1EB8 /* the _only_ mapping allowed for FX chips */ ! 116: ! 117: /*..*/ ! 118: #define ee_SIZE 0x40 /* total EEprom Size */ ! 119: #define ee_Checksum 0xBABA /* initial and final value for adding checksum */ ! 120: ! 121: ! 122: /* Card identification via EEprom: */ ! 123: #define ee_addr_vendor 0x10 /* Word offset for EISA Vendor ID */ ! 124: #define ee_addr_id 0x11 /* Word offset for Card ID */ ! 125: #define ee_addr_SN 0x12 /* Serial Number */ ! 126: #define ee_addr_CRC_8 0x14 /* CRC over last thee Bytes */ ! 127: ! 128: ! 129: #define ee_vendor_intel0 0x25 /* Vendor ID Intel */ ! 130: #define ee_vendor_intel1 0xD4 ! 131: #define ee_id_eepro10p0 0x10 /* ID for eepro/10+ */ ! 132: #define ee_id_eepro10p1 0x31 ! 133: ! 134: /* now this section could be used by both boards: the oldies and the ee10: ! 135: * ee10 uses tx buffer before of rx buffer and the oldies the inverse. ! 136: * (aris) ! 137: */ ! 138: #define RAM_SIZE 0x8000 ! 139: ! 140: #define RCV_HEADER 8 ! 141: #define RCV_DEFAULT_RAM 0x6000 ! 142: #define RCV_RAM rcv_ram ! 143: ! 144: static unsigned rcv_ram = RCV_DEFAULT_RAM; ! 145: ! 146: #define XMT_HEADER 8 ! 147: #define XMT_RAM (RAM_SIZE - RCV_RAM) ! 148: ! 149: #define XMT_START ((rcv_start + RCV_RAM) % RAM_SIZE) ! 150: ! 151: #define RCV_LOWER_LIMIT (rcv_start >> 8) ! 152: #define RCV_UPPER_LIMIT (((rcv_start + RCV_RAM) - 2) >> 8) ! 153: #define XMT_LOWER_LIMIT (XMT_START >> 8) ! 154: #define XMT_UPPER_LIMIT (((XMT_START + XMT_RAM) - 2) >> 8) ! 155: ! 156: #define RCV_START_PRO 0x00 ! 157: #define RCV_START_10 XMT_RAM ! 158: /* by default the old driver */ ! 159: static unsigned rcv_start = RCV_START_PRO; ! 160: ! 161: #define RCV_DONE 0x0008 ! 162: #define RX_OK 0x2000 ! 163: #define RX_ERROR 0x0d81 ! 164: ! 165: #define TX_DONE_BIT 0x0080 ! 166: #define CHAIN_BIT 0x8000 ! 167: #define XMT_STATUS 0x02 ! 168: #define XMT_CHAIN 0x04 ! 169: #define XMT_COUNT 0x06 ! 170: ! 171: #define BANK0_SELECT 0x00 ! 172: #define BANK1_SELECT 0x40 ! 173: #define BANK2_SELECT 0x80 ! 174: ! 175: /* Bank 0 registers */ ! 176: #define COMMAND_REG 0x00 /* Register 0 */ ! 177: #define MC_SETUP 0x03 ! 178: #define XMT_CMD 0x04 ! 179: #define DIAGNOSE_CMD 0x07 ! 180: #define RCV_ENABLE_CMD 0x08 ! 181: #define RCV_DISABLE_CMD 0x0a ! 182: #define STOP_RCV_CMD 0x0b ! 183: #define RESET_CMD 0x0e ! 184: #define POWER_DOWN_CMD 0x18 ! 185: #define RESUME_XMT_CMD 0x1c ! 186: #define SEL_RESET_CMD 0x1e ! 187: #define STATUS_REG 0x01 /* Register 1 */ ! 188: #define RX_INT 0x02 ! 189: #define TX_INT 0x04 ! 190: #define EXEC_STATUS 0x30 ! 191: #define ID_REG 0x02 /* Register 2 */ ! 192: #define R_ROBIN_BITS 0xc0 /* round robin counter */ ! 193: #define ID_REG_MASK 0x2c ! 194: #define ID_REG_SIG 0x24 ! 195: #define AUTO_ENABLE 0x10 ! 196: #define INT_MASK_REG 0x03 /* Register 3 */ ! 197: #define RX_STOP_MASK 0x01 ! 198: #define RX_MASK 0x02 ! 199: #define TX_MASK 0x04 ! 200: #define EXEC_MASK 0x08 ! 201: #define ALL_MASK 0x0f ! 202: #define IO_32_BIT 0x10 ! 203: #define RCV_BAR 0x04 /* The following are word (16-bit) registers */ ! 204: #define RCV_STOP 0x06 ! 205: ! 206: #define XMT_BAR_PRO 0x0a ! 207: #define XMT_BAR_10 0x0b ! 208: static unsigned xmt_bar = XMT_BAR_PRO; ! 209: ! 210: #define HOST_ADDRESS_REG 0x0c ! 211: #define IO_PORT 0x0e ! 212: #define IO_PORT_32_BIT 0x0c ! 213: ! 214: /* Bank 1 registers */ ! 215: #define REG1 0x01 ! 216: #define WORD_WIDTH 0x02 ! 217: #define INT_ENABLE 0x80 ! 218: #define INT_NO_REG 0x02 ! 219: #define RCV_LOWER_LIMIT_REG 0x08 ! 220: #define RCV_UPPER_LIMIT_REG 0x09 ! 221: ! 222: #define XMT_LOWER_LIMIT_REG_PRO 0x0a ! 223: #define XMT_UPPER_LIMIT_REG_PRO 0x0b ! 224: #define XMT_LOWER_LIMIT_REG_10 0x0b ! 225: #define XMT_UPPER_LIMIT_REG_10 0x0a ! 226: static unsigned xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_PRO; ! 227: static unsigned xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_PRO; ! 228: ! 229: /* Bank 2 registers */ ! 230: #define XMT_Chain_Int 0x20 /* Interrupt at the end of the transmit chain */ ! 231: #define XMT_Chain_ErrStop 0x40 /* Interrupt at the end of the chain even if there are errors */ ! 232: #define RCV_Discard_BadFrame 0x80 /* Throw bad frames away, and continue to receive others */ ! 233: #define REG2 0x02 ! 234: #define PRMSC_Mode 0x01 ! 235: #define Multi_IA 0x20 ! 236: #define REG3 0x03 ! 237: #define TPE_BIT 0x04 ! 238: #define BNC_BIT 0x20 ! 239: #define REG13 0x0d ! 240: #define FDX 0x00 ! 241: #define A_N_ENABLE 0x02 ! 242: ! 243: #define I_ADD_REG0 0x04 ! 244: #define I_ADD_REG1 0x05 ! 245: #define I_ADD_REG2 0x06 ! 246: #define I_ADD_REG3 0x07 ! 247: #define I_ADD_REG4 0x08 ! 248: #define I_ADD_REG5 0x09 ! 249: ! 250: #define EEPROM_REG_PRO 0x0a ! 251: #define EEPROM_REG_10 0x0b ! 252: static unsigned eeprom_reg = EEPROM_REG_PRO; ! 253: ! 254: #define EESK 0x01 ! 255: #define EECS 0x02 ! 256: #define EEDI 0x04 ! 257: #define EEDO 0x08 ! 258: ! 259: /* The horrible routine to read a word from the serial EEPROM. */ ! 260: /* IMPORTANT - the 82595 will be set to Bank 0 after the eeprom is read */ ! 261: ! 262: /* The delay between EEPROM clock transitions. */ ! 263: #define eeprom_delay() { udelay(40); } ! 264: #define EE_READ_CMD (6 << 6) ! 265: ! 266: /* do a full reset; data sheet asks for 250us delay */ ! 267: #define eepro_full_reset(ioaddr) outb(RESET_CMD, ioaddr); udelay(255); ! 268: ! 269: /* do a nice reset */ ! 270: #define eepro_sel_reset(ioaddr) \ ! 271: do { \ ! 272: outb ( SEL_RESET_CMD, ioaddr ); \ ! 273: (void) SLOW_DOWN; \ ! 274: (void) SLOW_DOWN; \ ! 275: } while (0) ! 276: ! 277: /* clear all interrupts */ ! 278: #define eepro_clear_int(ioaddr) outb(ALL_MASK, ioaddr + STATUS_REG) ! 279: ! 280: /* enable rx */ ! 281: #define eepro_en_rx(ioaddr) outb(RCV_ENABLE_CMD, ioaddr) ! 282: ! 283: /* disable rx */ ! 284: #define eepro_dis_rx(ioaddr) outb(RCV_DISABLE_CMD, ioaddr) ! 285: ! 286: /* switch bank */ ! 287: #define eepro_sw2bank0(ioaddr) outb(BANK0_SELECT, ioaddr) ! 288: #define eepro_sw2bank1(ioaddr) outb(BANK1_SELECT, ioaddr) ! 289: #define eepro_sw2bank2(ioaddr) outb(BANK2_SELECT, ioaddr) ! 290: ! 291: static unsigned int rx_start, tx_start; ! 292: static int tx_last; ! 293: static unsigned int tx_end; ! 294: static int eepro = 0; ! 295: static unsigned int mem_start, mem_end = RCV_DEFAULT_RAM / 1024; ! 296: ! 297: /************************************************************************** ! 298: RESET - Reset adapter ! 299: ***************************************************************************/ ! 300: static void eepro_reset(struct nic *nic) ! 301: { ! 302: int temp_reg, i; ! 303: ! 304: /* put the card in its initial state */ ! 305: eepro_sw2bank2(nic->ioaddr); /* be careful, bank2 now */ ! 306: temp_reg = inb(nic->ioaddr + eeprom_reg); ! 307: DBG("Stepping %d\n", temp_reg >> 5); ! 308: if (temp_reg & 0x10) /* check the TurnOff Enable bit */ ! 309: outb(temp_reg & 0xEF, nic->ioaddr + eeprom_reg); ! 310: for (i = 0; i < ETH_ALEN; i++) /* fill the MAC address */ ! 311: outb(nic->node_addr[i], nic->ioaddr + I_ADD_REG0 + i); ! 312: temp_reg = inb(nic->ioaddr + REG1); ! 313: /* setup Transmit Chaining and discard bad RCV frames */ ! 314: outb(temp_reg | XMT_Chain_Int | XMT_Chain_ErrStop ! 315: | RCV_Discard_BadFrame, nic->ioaddr + REG1); ! 316: temp_reg = inb(nic->ioaddr + REG2); /* match broadcast */ ! 317: outb(temp_reg | 0x14, nic->ioaddr + REG2); ! 318: temp_reg = inb(nic->ioaddr + REG3); ! 319: outb(temp_reg & 0x3F, nic->ioaddr + REG3); /* clear test mode */ ! 320: /* set the receiving mode */ ! 321: eepro_sw2bank1(nic->ioaddr); /* be careful, bank1 now */ ! 322: /* initialise the RCV and XMT upper and lower limits */ ! 323: outb(RCV_LOWER_LIMIT, nic->ioaddr + RCV_LOWER_LIMIT_REG); ! 324: outb(RCV_UPPER_LIMIT, nic->ioaddr + RCV_UPPER_LIMIT_REG); ! 325: outb(XMT_LOWER_LIMIT, nic->ioaddr + xmt_lower_limit_reg); ! 326: outb(XMT_UPPER_LIMIT, nic->ioaddr + xmt_upper_limit_reg); ! 327: eepro_sw2bank0(nic->ioaddr); /* Switch back to bank 0 */ ! 328: eepro_clear_int(nic->ioaddr); ! 329: /* Initialise RCV */ ! 330: outw(rx_start = (RCV_LOWER_LIMIT << 8), nic->ioaddr + RCV_BAR); ! 331: outw(((RCV_UPPER_LIMIT << 8) | 0xFE), nic->ioaddr + RCV_STOP); ! 332: /* Make sure 1st poll won't find a valid packet header */ ! 333: outw((RCV_LOWER_LIMIT << 8), nic->ioaddr + HOST_ADDRESS_REG); ! 334: outw(0, nic->ioaddr + IO_PORT); ! 335: /* Intialise XMT */ ! 336: outw((XMT_LOWER_LIMIT << 8), nic->ioaddr + xmt_bar); ! 337: eepro_sel_reset(nic->ioaddr); ! 338: tx_start = tx_end = (unsigned int) (XMT_LOWER_LIMIT << 8); ! 339: tx_last = 0; ! 340: eepro_en_rx(nic->ioaddr); ! 341: } ! 342: ! 343: /************************************************************************** ! 344: POLL - Wait for a frame ! 345: ***************************************************************************/ ! 346: static int eepro_poll(struct nic *nic, int retrieve) ! 347: { ! 348: unsigned int rcv_car = rx_start; ! 349: unsigned int rcv_event, rcv_status, rcv_next_frame, rcv_size; ! 350: ! 351: /* return true if there's an ethernet packet ready to read */ ! 352: /* nic->packet should contain data on return */ ! 353: /* nic->packetlen should contain length of data */ ! 354: #if 0 ! 355: if ((inb(nic->ioaddr + STATUS_REG) & 0x40) == 0) ! 356: return (0); ! 357: outb(0x40, nic->ioaddr + STATUS_REG); ! 358: #endif ! 359: outw(rcv_car, nic->ioaddr + HOST_ADDRESS_REG); ! 360: rcv_event = inw(nic->ioaddr + IO_PORT); ! 361: if (rcv_event != RCV_DONE) ! 362: return (0); ! 363: ! 364: /* FIXME: I'm guessing this might not work with this card, since ! 365: it looks like once a rcv_event is started it must be completed. ! 366: maybe there's another way. */ ! 367: if ( ! retrieve ) return 1; ! 368: ! 369: rcv_status = inw(nic->ioaddr + IO_PORT); ! 370: rcv_next_frame = inw(nic->ioaddr + IO_PORT); ! 371: rcv_size = inw(nic->ioaddr + IO_PORT); ! 372: #if 0 ! 373: printf("%hX %hX %d %hhX\n", rcv_status, rcv_next_frame, rcv_size, ! 374: inb(nic->ioaddr + STATUS_REG)); ! 375: #endif ! 376: if ((rcv_status & (RX_OK|RX_ERROR)) != RX_OK) { ! 377: printf("Receive error %hX\n", rcv_status); ! 378: return (0); ! 379: } ! 380: rcv_size &= 0x3FFF; ! 381: insw(nic->ioaddr + IO_PORT, nic->packet, ((rcv_size + 3) >> 1)); ! 382: #if 0 ! 383: { ! 384: int i; ! 385: for (i = 0; i < 48; i++) { ! 386: printf("%hhX", nic->packet[i]); ! 387: putchar(i % 16 == 15 ? '\n' : ' '); ! 388: } ! 389: } ! 390: #endif ! 391: nic->packetlen = rcv_size; ! 392: rcv_car = (rx_start + RCV_HEADER + rcv_size); ! 393: rx_start = rcv_next_frame; ! 394: /* ! 395: hex_dump(rcv_car, nic->packetlen); ! 396: */ ! 397: ! 398: if (rcv_car == 0) ! 399: rcv_car = ((RCV_UPPER_LIMIT << 8) | 0xff); ! 400: outw(rcv_car - 1, nic->ioaddr + RCV_STOP); ! 401: return (1); ! 402: } ! 403: ! 404: /************************************************************************** ! 405: TRANSMIT - Transmit a frame ! 406: ***************************************************************************/ ! 407: static void eepro_transmit( ! 408: struct nic *nic, ! 409: const char *d, /* Destination */ ! 410: unsigned int t, /* Type */ ! 411: unsigned int s, /* size */ ! 412: const char *p) /* Packet */ ! 413: { ! 414: unsigned int status, tx_available, last, end, length; ! 415: unsigned short type; ! 416: int boguscount = 20; ! 417: ! 418: length = s + ETH_HLEN; ! 419: if (tx_end > tx_start) ! 420: tx_available = XMT_RAM - (tx_end - tx_start); ! 421: else if (tx_end < tx_start) ! 422: tx_available = tx_start - tx_end; ! 423: else ! 424: tx_available = XMT_RAM; ! 425: assert ( length <= tx_available ); ! 426: last = tx_end; ! 427: end = last + (((length + 3) >> 1) << 1) + XMT_HEADER; ! 428: if (end >= (XMT_UPPER_LIMIT << 8)) { ! 429: last = (XMT_LOWER_LIMIT << 8); ! 430: end = last + (((length + 3) >> 1) << 1) + XMT_HEADER; ! 431: } ! 432: outw(last, nic->ioaddr + HOST_ADDRESS_REG); ! 433: outw(XMT_CMD, nic->ioaddr + IO_PORT); ! 434: outw(0, nic->ioaddr + IO_PORT); ! 435: outw(end, nic->ioaddr + IO_PORT); ! 436: outw(length, nic->ioaddr + IO_PORT); ! 437: outsw(nic->ioaddr + IO_PORT, d, ETH_ALEN / 2); ! 438: outsw(nic->ioaddr + IO_PORT, nic->node_addr, ETH_ALEN / 2); ! 439: type = htons(t); ! 440: outsw(nic->ioaddr + IO_PORT, &type, sizeof(type) / 2); ! 441: outsw(nic->ioaddr + IO_PORT, p, (s + 3) >> 1); ! 442: /* A dummy read to flush the DRAM write pipeline */ ! 443: status = inw(nic->ioaddr + IO_PORT); ! 444: outw(last, nic->ioaddr + xmt_bar); ! 445: outb(XMT_CMD, nic->ioaddr); ! 446: tx_start = last; ! 447: tx_last = last; ! 448: tx_end = end; ! 449: #if 0 ! 450: printf("%d %d\n", tx_start, tx_end); ! 451: #endif ! 452: while (boguscount > 0) { ! 453: if (((status = inw(nic->ioaddr + IO_PORT)) & TX_DONE_BIT) == 0) { ! 454: udelay(40); ! 455: boguscount--; ! 456: continue; ! 457: } ! 458: if ((status & 0x2000) == 0) { ! 459: DBG("Transmit status %hX\n", status); ! 460: } ! 461: } ! 462: } ! 463: ! 464: /************************************************************************** ! 465: DISABLE - Turn off ethernet interface ! 466: ***************************************************************************/ ! 467: static void eepro_disable ( struct nic *nic, struct isa_device *isa __unused ) { ! 468: eepro_sw2bank0(nic->ioaddr); /* Switch to bank 0 */ ! 469: /* Flush the Tx and disable Rx */ ! 470: outb(STOP_RCV_CMD, nic->ioaddr); ! 471: tx_start = tx_end = (XMT_LOWER_LIMIT << 8); ! 472: tx_last = 0; ! 473: /* Reset the 82595 */ ! 474: eepro_full_reset(nic->ioaddr); ! 475: } ! 476: ! 477: /************************************************************************** ! 478: DISABLE - Enable, Disable, or Force interrupts ! 479: ***************************************************************************/ ! 480: static void eepro_irq(struct nic *nic __unused, irq_action_t action __unused) ! 481: { ! 482: switch ( action ) { ! 483: case DISABLE : ! 484: break; ! 485: case ENABLE : ! 486: break; ! 487: case FORCE : ! 488: break; ! 489: } ! 490: } ! 491: ! 492: static int read_eeprom(uint16_t ioaddr, int location) ! 493: { ! 494: int i; ! 495: unsigned short retval = 0; ! 496: int ee_addr = ioaddr + eeprom_reg; ! 497: int read_cmd = location | EE_READ_CMD; ! 498: int ctrl_val = EECS; ! 499: ! 500: if (eepro == LAN595FX_10ISA) { ! 501: eepro_sw2bank1(ioaddr); ! 502: outb(0x00, ioaddr + STATUS_REG); ! 503: } ! 504: eepro_sw2bank2(ioaddr); ! 505: outb(ctrl_val, ee_addr); ! 506: /* shift the read command bits out */ ! 507: for (i = 8; i >= 0; i--) { ! 508: short outval = (read_cmd & (1 << i)) ? ctrl_val | EEDI : ctrl_val; ! 509: outb(outval, ee_addr); ! 510: outb(outval | EESK, ee_addr); /* EEPROM clock tick */ ! 511: eeprom_delay(); ! 512: outb(outval, ee_addr); /* finish EEPROM clock tick */ ! 513: eeprom_delay(); ! 514: } ! 515: outb(ctrl_val, ee_addr); ! 516: for (i = 16; i > 0; i--) { ! 517: outb(ctrl_val | EESK, ee_addr); ! 518: eeprom_delay(); ! 519: retval = (retval << 1) | ((inb(ee_addr) & EEDO) ? 1 : 0); ! 520: outb(ctrl_val, ee_addr); ! 521: eeprom_delay(); ! 522: } ! 523: /* terminate the EEPROM access */ ! 524: ctrl_val &= ~EECS; ! 525: outb(ctrl_val | EESK, ee_addr); ! 526: eeprom_delay(); ! 527: outb(ctrl_val, ee_addr); ! 528: eeprom_delay(); ! 529: eepro_sw2bank0(ioaddr); ! 530: return (retval); ! 531: } ! 532: ! 533: static int eepro_probe1 ( isa_probe_addr_t ioaddr ) { ! 534: int id, counter; ! 535: ! 536: id = inb(ioaddr + ID_REG); ! 537: if ((id & ID_REG_MASK) != ID_REG_SIG) ! 538: return (0); ! 539: counter = id & R_ROBIN_BITS; ! 540: if (((id = inb(ioaddr + ID_REG)) & R_ROBIN_BITS) != (counter + 0x40)) ! 541: return (0); ! 542: /* yes the 82595 has been found */ ! 543: return (1); ! 544: } ! 545: ! 546: static struct nic_operations eepro_operations = { ! 547: .connect = dummy_connect, ! 548: .poll = eepro_poll, ! 549: .transmit = eepro_transmit, ! 550: .irq = eepro_irq, ! 551: ! 552: }; ! 553: ! 554: /************************************************************************** ! 555: PROBE - Look for an adapter, this routine's visible to the outside ! 556: ***************************************************************************/ ! 557: static int eepro_probe ( struct nic *nic, struct isa_device *isa ) { ! 558: ! 559: int i, l_eepro = 0; ! 560: union { ! 561: unsigned char caddr[ETH_ALEN]; ! 562: unsigned short saddr[ETH_ALEN/2]; ! 563: } station_addr; ! 564: const char *name; ! 565: ! 566: nic->irqno = 0; ! 567: nic->ioaddr = isa->ioaddr; ! 568: ! 569: station_addr.saddr[2] = read_eeprom(nic->ioaddr,2); ! 570: if ( ( station_addr.saddr[2] == 0x0000 ) || ! 571: ( station_addr.saddr[2] == 0xFFFF ) ) { ! 572: l_eepro = 3; ! 573: eepro = LAN595FX_10ISA; ! 574: eeprom_reg= EEPROM_REG_10; ! 575: rcv_start = RCV_START_10; ! 576: xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_10; ! 577: xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_10; ! 578: station_addr.saddr[2] = read_eeprom(nic->ioaddr,2); ! 579: } ! 580: station_addr.saddr[1] = read_eeprom(nic->ioaddr,3); ! 581: station_addr.saddr[0] = read_eeprom(nic->ioaddr,4); ! 582: if (l_eepro) ! 583: name = "Intel EtherExpress 10 ISA"; ! 584: else if (read_eeprom(nic->ioaddr,7) == ee_FX_INT2IRQ) { ! 585: name = "Intel EtherExpress Pro/10+ ISA"; ! 586: l_eepro = 2; ! 587: } else if (station_addr.saddr[0] == SA_ADDR1) { ! 588: name = "Intel EtherExpress Pro/10 ISA"; ! 589: l_eepro = 1; ! 590: } else { ! 591: l_eepro = 0; ! 592: name = "Intel 82595-based LAN card"; ! 593: } ! 594: station_addr.saddr[0] = swap16(station_addr.saddr[0]); ! 595: station_addr.saddr[1] = swap16(station_addr.saddr[1]); ! 596: station_addr.saddr[2] = swap16(station_addr.saddr[2]); ! 597: for (i = 0; i < ETH_ALEN; i++) { ! 598: nic->node_addr[i] = station_addr.caddr[i]; ! 599: } ! 600: ! 601: DBG ( "%s ioaddr %#hX, addr %s", name, nic->ioaddr, eth_ntoa ( nic->node_addr ) ); ! 602: ! 603: mem_start = RCV_LOWER_LIMIT << 8; ! 604: if ((mem_end & 0x3F) < 3 || (mem_end & 0x3F) > 29) ! 605: mem_end = RCV_UPPER_LIMIT << 8; ! 606: else { ! 607: mem_end = mem_end * 1024 + (RCV_LOWER_LIMIT << 8); ! 608: rcv_ram = mem_end - (RCV_LOWER_LIMIT << 8); ! 609: } ! 610: printf(", Rx mem %dK, if %s\n", (mem_end - mem_start) >> 10, ! 611: GetBit(read_eeprom(nic->ioaddr,5), ee_BNC_TPE) ? "BNC" : "TP"); ! 612: ! 613: eepro_reset(nic); ! 614: ! 615: /* point to NIC specific routines */ ! 616: nic->nic_op = &eepro_operations; ! 617: return 1; ! 618: } ! 619: ! 620: static isa_probe_addr_t eepro_probe_addrs[] = { ! 621: 0x300, 0x210, 0x240, 0x280, 0x2C0, 0x200, 0x320, 0x340, 0x360, ! 622: }; ! 623: ! 624: ISA_DRIVER ( eepro_driver, eepro_probe_addrs, eepro_probe1, ! 625: GENERIC_ISAPNP_VENDOR, 0x828a ); ! 626: ! 627: DRIVER ( "eepro", nic_driver, isa_driver, eepro_driver, ! 628: eepro_probe, eepro_disable ); ! 629: ! 630: ISA_ROM ( "eepro", "Intel Etherexpress Pro/10" ); ! 631: ! 632: /* ! 633: * Local variables: ! 634: * c-basic-offset: 8 ! 635: * c-indent-level: 8 ! 636: * tab-width: 8 ! 637: * End: ! 638: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.