00001 #ifdef ALLMULTI
00002 #error multicast support is not yet implemented
00003 #endif
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 FILE_LICENCE ( GPL2_OR_LATER );
00035
00036 #include "etherboot.h"
00037 #include <errno.h>
00038 #include "nic.h"
00039 #include <gpxe/isa.h>
00040 #include <gpxe/ethernet.h>
00041
00042
00043 #define LAN595 0
00044 #define LAN595TX 1
00045 #define LAN595FX 2
00046 #define LAN595FX_10ISA 3
00047
00048 #define SLOW_DOWN inb(0x80);
00049
00050
00051 #define SA_ADDR0 0x00
00052 #define SA_ADDR1 0xaa
00053 #define SA_ADDR2 0x00
00054
00055 #define GetBit(x,y) ((x & (1<<y))>>y)
00056
00057
00058 #define ee_PnP 0
00059 #define ee_Word1 1
00060 #define ee_BusWidth 2
00061 #define ee_FlashAddr 3
00062 #define ee_FlashMask 0x7
00063 #define ee_AutoIO 6
00064 #define ee_reserved0 7
00065 #define ee_Flash 8
00066 #define ee_AutoNeg 9
00067 #define ee_IO0 10
00068 #define ee_IO0Mask 0x
00069 #define ee_IO1 15
00070
00071
00072 #define ee_IntSel 0
00073 #define ee_IntMask 0x7
00074 #define ee_LI 3
00075 #define ee_PC 4
00076 #define ee_TPE_AUI 5
00077 #define ee_Jabber 6
00078 #define ee_AutoPort 7
00079 #define ee_SMOUT 8
00080 #define ee_PROM 9
00081 #define ee_reserved1 10
00082 #define ee_AltReady 13
00083 #define ee_reserved2 14
00084 #define ee_Duplex 15
00085
00086
00087 #define ee_IA5 0
00088 #define ee_IA4 8
00089 #define ee_IA3 0
00090 #define ee_IA2 8
00091 #define ee_IA1 0
00092 #define ee_IA0 8
00093
00094
00095 #define ee_BNC_TPE 0
00096 #define ee_BootType 1
00097 #define ee_BootTypeMask 0x3
00098 #define ee_NumConn 3
00099 #define ee_FlashSock 4
00100 #define ee_PortTPE 5
00101 #define ee_PortBNC 6
00102 #define ee_PortAUI 7
00103 #define ee_PowerMgt 10
00104 #define ee_CP 13
00105 #define ee_CPMask 0x7
00106
00107
00108 #define ee_Stepping 0
00109 #define ee_StepMask 0x0F
00110 #define ee_BoardID 4
00111 #define ee_BoardMask 0x0FFF
00112
00113
00114 #define ee_INT_TO_IRQ 0
00115 #define ee_FX_INT2IRQ 0x1EB8
00116
00117
00118 #define ee_SIZE 0x40
00119 #define ee_Checksum 0xBABA
00120
00121
00122
00123 #define ee_addr_vendor 0x10
00124 #define ee_addr_id 0x11
00125 #define ee_addr_SN 0x12
00126 #define ee_addr_CRC_8 0x14
00127
00128
00129 #define ee_vendor_intel0 0x25
00130 #define ee_vendor_intel1 0xD4
00131 #define ee_id_eepro10p0 0x10
00132 #define ee_id_eepro10p1 0x31
00133
00134
00135
00136
00137
00138 #define RAM_SIZE 0x8000
00139
00140 #define RCV_HEADER 8
00141 #define RCV_DEFAULT_RAM 0x6000
00142 #define RCV_RAM rcv_ram
00143
00144 static unsigned rcv_ram = RCV_DEFAULT_RAM;
00145
00146 #define XMT_HEADER 8
00147 #define XMT_RAM (RAM_SIZE - RCV_RAM)
00148
00149 #define XMT_START ((rcv_start + RCV_RAM) % RAM_SIZE)
00150
00151 #define RCV_LOWER_LIMIT (rcv_start >> 8)
00152 #define RCV_UPPER_LIMIT (((rcv_start + RCV_RAM) - 2) >> 8)
00153 #define XMT_LOWER_LIMIT (XMT_START >> 8)
00154 #define XMT_UPPER_LIMIT (((XMT_START + XMT_RAM) - 2) >> 8)
00155
00156 #define RCV_START_PRO 0x00
00157 #define RCV_START_10 XMT_RAM
00158
00159 static unsigned rcv_start = RCV_START_PRO;
00160
00161 #define RCV_DONE 0x0008
00162 #define RX_OK 0x2000
00163 #define RX_ERROR 0x0d81
00164
00165 #define TX_DONE_BIT 0x0080
00166 #define CHAIN_BIT 0x8000
00167 #define XMT_STATUS 0x02
00168 #define XMT_CHAIN 0x04
00169 #define XMT_COUNT 0x06
00170
00171 #define BANK0_SELECT 0x00
00172 #define BANK1_SELECT 0x40
00173 #define BANK2_SELECT 0x80
00174
00175
00176 #define COMMAND_REG 0x00
00177 #define MC_SETUP 0x03
00178 #define XMT_CMD 0x04
00179 #define DIAGNOSE_CMD 0x07
00180 #define RCV_ENABLE_CMD 0x08
00181 #define RCV_DISABLE_CMD 0x0a
00182 #define STOP_RCV_CMD 0x0b
00183 #define RESET_CMD 0x0e
00184 #define POWER_DOWN_CMD 0x18
00185 #define RESUME_XMT_CMD 0x1c
00186 #define SEL_RESET_CMD 0x1e
00187 #define STATUS_REG 0x01
00188 #define RX_INT 0x02
00189 #define TX_INT 0x04
00190 #define EXEC_STATUS 0x30
00191 #define ID_REG 0x02
00192 #define R_ROBIN_BITS 0xc0
00193 #define ID_REG_MASK 0x2c
00194 #define ID_REG_SIG 0x24
00195 #define AUTO_ENABLE 0x10
00196 #define INT_MASK_REG 0x03
00197 #define RX_STOP_MASK 0x01
00198 #define RX_MASK 0x02
00199 #define TX_MASK 0x04
00200 #define EXEC_MASK 0x08
00201 #define ALL_MASK 0x0f
00202 #define IO_32_BIT 0x10
00203 #define RCV_BAR 0x04
00204 #define RCV_STOP 0x06
00205
00206 #define XMT_BAR_PRO 0x0a
00207 #define XMT_BAR_10 0x0b
00208 static unsigned xmt_bar = XMT_BAR_PRO;
00209
00210 #define HOST_ADDRESS_REG 0x0c
00211 #define IO_PORT 0x0e
00212 #define IO_PORT_32_BIT 0x0c
00213
00214
00215 #define REG1 0x01
00216 #define WORD_WIDTH 0x02
00217 #define INT_ENABLE 0x80
00218 #define INT_NO_REG 0x02
00219 #define RCV_LOWER_LIMIT_REG 0x08
00220 #define RCV_UPPER_LIMIT_REG 0x09
00221
00222 #define XMT_LOWER_LIMIT_REG_PRO 0x0a
00223 #define XMT_UPPER_LIMIT_REG_PRO 0x0b
00224 #define XMT_LOWER_LIMIT_REG_10 0x0b
00225 #define XMT_UPPER_LIMIT_REG_10 0x0a
00226 static unsigned xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_PRO;
00227 static unsigned xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_PRO;
00228
00229
00230 #define XMT_Chain_Int 0x20
00231 #define XMT_Chain_ErrStop 0x40
00232 #define RCV_Discard_BadFrame 0x80
00233 #define REG2 0x02
00234 #define PRMSC_Mode 0x01
00235 #define Multi_IA 0x20
00236 #define REG3 0x03
00237 #define TPE_BIT 0x04
00238 #define BNC_BIT 0x20
00239 #define REG13 0x0d
00240 #define FDX 0x00
00241 #define A_N_ENABLE 0x02
00242
00243 #define I_ADD_REG0 0x04
00244 #define I_ADD_REG1 0x05
00245 #define I_ADD_REG2 0x06
00246 #define I_ADD_REG3 0x07
00247 #define I_ADD_REG4 0x08
00248 #define I_ADD_REG5 0x09
00249
00250 #define EEPROM_REG_PRO 0x0a
00251 #define EEPROM_REG_10 0x0b
00252 static unsigned eeprom_reg = EEPROM_REG_PRO;
00253
00254 #define EESK 0x01
00255 #define EECS 0x02
00256 #define EEDI 0x04
00257 #define EEDO 0x08
00258
00259
00260
00261
00262
00263 #define eeprom_delay() { udelay(40); }
00264 #define EE_READ_CMD (6 << 6)
00265
00266
00267 #define eepro_full_reset(ioaddr) outb(RESET_CMD, ioaddr); udelay(255);
00268
00269
00270 #define eepro_sel_reset(ioaddr) \
00271 do { \
00272 outb ( SEL_RESET_CMD, ioaddr ); \
00273 (void) SLOW_DOWN; \
00274 (void) SLOW_DOWN; \
00275 } while (0)
00276
00277
00278 #define eepro_clear_int(ioaddr) outb(ALL_MASK, ioaddr + STATUS_REG)
00279
00280
00281 #define eepro_en_rx(ioaddr) outb(RCV_ENABLE_CMD, ioaddr)
00282
00283
00284 #define eepro_dis_rx(ioaddr) outb(RCV_DISABLE_CMD, ioaddr)
00285
00286
00287 #define eepro_sw2bank0(ioaddr) outb(BANK0_SELECT, ioaddr)
00288 #define eepro_sw2bank1(ioaddr) outb(BANK1_SELECT, ioaddr)
00289 #define eepro_sw2bank2(ioaddr) outb(BANK2_SELECT, ioaddr)
00290
00291 static unsigned int rx_start, tx_start;
00292 static int tx_last;
00293 static unsigned int tx_end;
00294 static int eepro = 0;
00295 static unsigned int mem_start, mem_end = RCV_DEFAULT_RAM / 1024;
00296
00297
00298
00299
00300 static void eepro_reset(struct nic *nic)
00301 {
00302 int temp_reg, i;
00303
00304
00305 eepro_sw2bank2(nic->ioaddr);
00306 temp_reg = inb(nic->ioaddr + eeprom_reg);
00307 DBG("Stepping %d\n", temp_reg >> 5);
00308 if (temp_reg & 0x10)
00309 outb(temp_reg & 0xEF, nic->ioaddr + eeprom_reg);
00310 for (i = 0; i < ETH_ALEN; i++)
00311 outb(nic->node_addr[i], nic->ioaddr + I_ADD_REG0 + i);
00312 temp_reg = inb(nic->ioaddr + REG1);
00313
00314 outb(temp_reg | XMT_Chain_Int | XMT_Chain_ErrStop
00315 | RCV_Discard_BadFrame, nic->ioaddr + REG1);
00316 temp_reg = inb(nic->ioaddr + REG2);
00317 outb(temp_reg | 0x14, nic->ioaddr + REG2);
00318 temp_reg = inb(nic->ioaddr + REG3);
00319 outb(temp_reg & 0x3F, nic->ioaddr + REG3);
00320
00321 eepro_sw2bank1(nic->ioaddr);
00322
00323 outb(RCV_LOWER_LIMIT, nic->ioaddr + RCV_LOWER_LIMIT_REG);
00324 outb(RCV_UPPER_LIMIT, nic->ioaddr + RCV_UPPER_LIMIT_REG);
00325 outb(XMT_LOWER_LIMIT, nic->ioaddr + xmt_lower_limit_reg);
00326 outb(XMT_UPPER_LIMIT, nic->ioaddr + xmt_upper_limit_reg);
00327 eepro_sw2bank0(nic->ioaddr);
00328 eepro_clear_int(nic->ioaddr);
00329
00330 outw(rx_start = (RCV_LOWER_LIMIT << 8), nic->ioaddr + RCV_BAR);
00331 outw(((RCV_UPPER_LIMIT << 8) | 0xFE), nic->ioaddr + RCV_STOP);
00332
00333 outw((RCV_LOWER_LIMIT << 8), nic->ioaddr + HOST_ADDRESS_REG);
00334 outw(0, nic->ioaddr + IO_PORT);
00335
00336 outw((XMT_LOWER_LIMIT << 8), nic->ioaddr + xmt_bar);
00337 eepro_sel_reset(nic->ioaddr);
00338 tx_start = tx_end = (unsigned int) (XMT_LOWER_LIMIT << 8);
00339 tx_last = 0;
00340 eepro_en_rx(nic->ioaddr);
00341 }
00342
00343
00344
00345
00346 static int eepro_poll(struct nic *nic, int retrieve)
00347 {
00348 unsigned int rcv_car = rx_start;
00349 unsigned int rcv_event, rcv_status, rcv_next_frame, rcv_size;
00350
00351
00352
00353
00354 #if 0
00355 if ((inb(nic->ioaddr + STATUS_REG) & 0x40) == 0)
00356 return (0);
00357 outb(0x40, nic->ioaddr + STATUS_REG);
00358 #endif
00359 outw(rcv_car, nic->ioaddr + HOST_ADDRESS_REG);
00360 rcv_event = inw(nic->ioaddr + IO_PORT);
00361 if (rcv_event != RCV_DONE)
00362 return (0);
00363
00364
00365
00366
00367 if ( ! retrieve ) return 1;
00368
00369 rcv_status = inw(nic->ioaddr + IO_PORT);
00370 rcv_next_frame = inw(nic->ioaddr + IO_PORT);
00371 rcv_size = inw(nic->ioaddr + IO_PORT);
00372 #if 0
00373 printf("%hX %hX %d %hhX\n", rcv_status, rcv_next_frame, rcv_size,
00374 inb(nic->ioaddr + STATUS_REG));
00375 #endif
00376 if ((rcv_status & (RX_OK|RX_ERROR)) != RX_OK) {
00377 printf("Receive error %hX\n", rcv_status);
00378 return (0);
00379 }
00380 rcv_size &= 0x3FFF;
00381 insw(nic->ioaddr + IO_PORT, nic->packet, ((rcv_size + 3) >> 1));
00382 #if 0
00383 {
00384 int i;
00385 for (i = 0; i < 48; i++) {
00386 printf("%hhX", nic->packet[i]);
00387 putchar(i % 16 == 15 ? '\n' : ' ');
00388 }
00389 }
00390 #endif
00391 nic->packetlen = rcv_size;
00392 rcv_car = (rx_start + RCV_HEADER + rcv_size);
00393 rx_start = rcv_next_frame;
00394
00395
00396
00397
00398 if (rcv_car == 0)
00399 rcv_car = ((RCV_UPPER_LIMIT << 8) | 0xff);
00400 outw(rcv_car - 1, nic->ioaddr + RCV_STOP);
00401 return (1);
00402 }
00403
00404
00405
00406
00407 static void eepro_transmit(
00408 struct nic *nic,
00409 const char *d,
00410 unsigned int t,
00411 unsigned int s,
00412 const char *p)
00413 {
00414 unsigned int status, tx_available, last, end, length;
00415 unsigned short type;
00416 int boguscount = 20;
00417
00418 length = s + ETH_HLEN;
00419 if (tx_end > tx_start)
00420 tx_available = XMT_RAM - (tx_end - tx_start);
00421 else if (tx_end < tx_start)
00422 tx_available = tx_start - tx_end;
00423 else
00424 tx_available = XMT_RAM;
00425 last = tx_end;
00426 end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
00427 if (end >= (XMT_UPPER_LIMIT << 8)) {
00428 last = (XMT_LOWER_LIMIT << 8);
00429 end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
00430 }
00431 outw(last, nic->ioaddr + HOST_ADDRESS_REG);
00432 outw(XMT_CMD, nic->ioaddr + IO_PORT);
00433 outw(0, nic->ioaddr + IO_PORT);
00434 outw(end, nic->ioaddr + IO_PORT);
00435 outw(length, nic->ioaddr + IO_PORT);
00436 outsw(nic->ioaddr + IO_PORT, d, ETH_ALEN / 2);
00437 outsw(nic->ioaddr + IO_PORT, nic->node_addr, ETH_ALEN / 2);
00438 type = htons(t);
00439 outsw(nic->ioaddr + IO_PORT, &type, sizeof(type) / 2);
00440 outsw(nic->ioaddr + IO_PORT, p, (s + 3) >> 1);
00441
00442 status = inw(nic->ioaddr + IO_PORT);
00443 outw(last, nic->ioaddr + xmt_bar);
00444 outb(XMT_CMD, nic->ioaddr);
00445 tx_start = last;
00446 tx_last = last;
00447 tx_end = end;
00448 #if 0
00449 printf("%d %d\n", tx_start, tx_end);
00450 #endif
00451 while (boguscount > 0) {
00452 if (((status = inw(nic->ioaddr + IO_PORT)) & TX_DONE_BIT) == 0) {
00453 udelay(40);
00454 boguscount--;
00455 continue;
00456 }
00457 if ((status & 0x2000) == 0) {
00458 DBG("Transmit status %hX\n", status);
00459 }
00460 }
00461 }
00462
00463
00464
00465
00466 static void eepro_disable ( struct nic *nic, struct isa_device *isa __unused ) {
00467 eepro_sw2bank0(nic->ioaddr);
00468
00469 outb(STOP_RCV_CMD, nic->ioaddr);
00470 tx_start = tx_end = (XMT_LOWER_LIMIT << 8);
00471 tx_last = 0;
00472
00473 eepro_full_reset(nic->ioaddr);
00474 }
00475
00476
00477
00478
00479 static void eepro_irq(struct nic *nic __unused, irq_action_t action __unused)
00480 {
00481 switch ( action ) {
00482 case DISABLE :
00483 break;
00484 case ENABLE :
00485 break;
00486 case FORCE :
00487 break;
00488 }
00489 }
00490
00491 static int read_eeprom(uint16_t ioaddr, int location)
00492 {
00493 int i;
00494 unsigned short retval = 0;
00495 int ee_addr = ioaddr + eeprom_reg;
00496 int read_cmd = location | EE_READ_CMD;
00497 int ctrl_val = EECS;
00498
00499 if (eepro == LAN595FX_10ISA) {
00500 eepro_sw2bank1(ioaddr);
00501 outb(0x00, ioaddr + STATUS_REG);
00502 }
00503 eepro_sw2bank2(ioaddr);
00504 outb(ctrl_val, ee_addr);
00505
00506 for (i = 8; i >= 0; i--) {
00507 short outval = (read_cmd & (1 << i)) ? ctrl_val | EEDI : ctrl_val;
00508 outb(outval, ee_addr);
00509 outb(outval | EESK, ee_addr);
00510 eeprom_delay();
00511 outb(outval, ee_addr);
00512 eeprom_delay();
00513 }
00514 outb(ctrl_val, ee_addr);
00515 for (i = 16; i > 0; i--) {
00516 outb(ctrl_val | EESK, ee_addr);
00517 eeprom_delay();
00518 retval = (retval << 1) | ((inb(ee_addr) & EEDO) ? 1 : 0);
00519 outb(ctrl_val, ee_addr);
00520 eeprom_delay();
00521 }
00522
00523 ctrl_val &= ~EECS;
00524 outb(ctrl_val | EESK, ee_addr);
00525 eeprom_delay();
00526 outb(ctrl_val, ee_addr);
00527 eeprom_delay();
00528 eepro_sw2bank0(ioaddr);
00529 return (retval);
00530 }
00531
00532 static int eepro_probe1 ( isa_probe_addr_t ioaddr ) {
00533 int id, counter;
00534
00535 id = inb(ioaddr + ID_REG);
00536 if ((id & ID_REG_MASK) != ID_REG_SIG)
00537 return (0);
00538 counter = id & R_ROBIN_BITS;
00539 if (((id = inb(ioaddr + ID_REG)) & R_ROBIN_BITS) != (counter + 0x40))
00540 return (0);
00541
00542 return (1);
00543 }
00544
00545 static struct nic_operations eepro_operations = {
00546 .connect = dummy_connect,
00547 .poll = eepro_poll,
00548 .transmit = eepro_transmit,
00549 .irq = eepro_irq,
00550
00551 };
00552
00553
00554
00555
00556 static int eepro_probe ( struct nic *nic, struct isa_device *isa ) {
00557
00558 int i, l_eepro = 0;
00559 union {
00560 unsigned char caddr[ETH_ALEN];
00561 unsigned short saddr[ETH_ALEN/2];
00562 } station_addr;
00563 const char *name;
00564
00565 nic->irqno = 0;
00566 nic->ioaddr = isa->ioaddr;
00567
00568 station_addr.saddr[2] = read_eeprom(nic->ioaddr,2);
00569 if ( ( station_addr.saddr[2] == 0x0000 ) ||
00570 ( station_addr.saddr[2] == 0xFFFF ) ) {
00571 l_eepro = 3;
00572 eepro = LAN595FX_10ISA;
00573 eeprom_reg= EEPROM_REG_10;
00574 rcv_start = RCV_START_10;
00575 xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_10;
00576 xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_10;
00577 station_addr.saddr[2] = read_eeprom(nic->ioaddr,2);
00578 }
00579 station_addr.saddr[1] = read_eeprom(nic->ioaddr,3);
00580 station_addr.saddr[0] = read_eeprom(nic->ioaddr,4);
00581 if (l_eepro)
00582 name = "Intel EtherExpress 10 ISA";
00583 else if (read_eeprom(nic->ioaddr,7) == ee_FX_INT2IRQ) {
00584 name = "Intel EtherExpress Pro/10+ ISA";
00585 l_eepro = 2;
00586 } else if (station_addr.saddr[0] == SA_ADDR1) {
00587 name = "Intel EtherExpress Pro/10 ISA";
00588 l_eepro = 1;
00589 } else {
00590 l_eepro = 0;
00591 name = "Intel 82595-based LAN card";
00592 }
00593 station_addr.saddr[0] = swap16(station_addr.saddr[0]);
00594 station_addr.saddr[1] = swap16(station_addr.saddr[1]);
00595 station_addr.saddr[2] = swap16(station_addr.saddr[2]);
00596 for (i = 0; i < ETH_ALEN; i++) {
00597 nic->node_addr[i] = station_addr.caddr[i];
00598 }
00599
00600 DBG ( "%s ioaddr %#hX, addr %s", name, nic->ioaddr, eth_ntoa ( nic->node_addr ) );
00601
00602 mem_start = RCV_LOWER_LIMIT << 8;
00603 if ((mem_end & 0x3F) < 3 || (mem_end & 0x3F) > 29)
00604 mem_end = RCV_UPPER_LIMIT << 8;
00605 else {
00606 mem_end = mem_end * 1024 + (RCV_LOWER_LIMIT << 8);
00607 rcv_ram = mem_end - (RCV_LOWER_LIMIT << 8);
00608 }
00609 printf(", Rx mem %dK, if %s\n", (mem_end - mem_start) >> 10,
00610 GetBit(read_eeprom(nic->ioaddr,5), ee_BNC_TPE) ? "BNC" : "TP");
00611
00612 eepro_reset(nic);
00613
00614
00615 nic->nic_op = &eepro_operations;
00616 return 1;
00617 }
00618
00619 static isa_probe_addr_t eepro_probe_addrs[] = {
00620 0x300, 0x210, 0x240, 0x280, 0x2C0, 0x200, 0x320, 0x340, 0x360,
00621 };
00622
00623 ISA_DRIVER ( eepro_driver, eepro_probe_addrs, eepro_probe1,
00624 GENERIC_ISAPNP_VENDOR, 0x828a );
00625
00626 DRIVER ( "eepro", nic_driver, isa_driver, eepro_driver,
00627 eepro_probe, eepro_disable );
00628
00629 ISA_ROM ( "eepro", "Intel Etherexpress Pro/10" );
00630
00631
00632
00633
00634
00635
00636
00637