1 /* 2 * lance.c 3 * 4 * This file contains a ethernet device driver for AMD LANCE based ethernet 5 * cards. 6 * 7 * Created: Jul 27, 2002 by Kazuya Kodama <kazuya@nii.ac.jp> 8 * Adapted for Minix 3: Sep 05, 2005 by Joren l'Ami <jwlami@cs.vu.nl> 9 */ 10 11 #define VERBOSE 0 /* Verbose debugging output */ 12 #define LANCE_FKEY 0 /* Use function key to dump Lance stats */ 13 14 #include <minix/drivers.h> 15 #include <minix/netdriver.h> 16 17 #include <assert.h> 18 19 #include <minix/syslib.h> 20 #include <minix/endpoint.h> 21 #include <machine/pci.h> 22 #include <minix/ds.h> 23 24 #include "lance.h" 25 26 static int do_init(unsigned int instance, netdriver_addr_t *addr, 27 uint32_t *caps, unsigned int *ticks); 28 static void ec_confaddr(netdriver_addr_t *addr, unsigned int instance); 29 static void ec_reinit(ether_card_t *ec); 30 static void do_intr(unsigned int mask); 31 static void do_set_mode(unsigned int mode, const netdriver_addr_t *mcast_list, 32 unsigned int mcast_count); 33 static int do_send(struct netdriver_data *data, size_t size); 34 static ssize_t do_recv(struct netdriver_data *data, size_t max); 35 static void do_stop(void); 36 static void lance_dump(void); 37 static void do_other(const message *m_ptr, int ipc_status); 38 static void get_addressing(int devind, ether_card_t *ec); 39 static int lance_probe(ether_card_t *ec, unsigned int skip); 40 static void lance_init_hw(ether_card_t *ec, netdriver_addr_t *addr, 41 unsigned int instance); 42 43 /* Accesses Lance Control and Status Registers */ 44 static u8_t in_byte(port_t port); 45 static u16_t in_word(port_t port); 46 static void out_word(port_t port, u16_t value); 47 static u16_t read_csr(port_t ioaddr, u16_t csrno); 48 static void write_csr(port_t ioaddr, u16_t csrno, u16_t value); 49 50 static ether_card_t ec_state; 51 52 /* --- LANCE --- */ 53 /* General */ 54 typedef uint32_t Address; 55 56 #define ETH_FRAME_LEN 1518 57 58 #define LANCE_MUST_PAD 0x00000001 59 #define LANCE_ENABLE_AUTOSELECT 0x00000002 60 #define LANCE_SELECT_PHONELINE 0x00000004 61 #define LANCE_MUST_UNRESET 0x00000008 62 63 static const struct lance_chip_type 64 { 65 int id_number; 66 const char *name; 67 int flags; 68 } chip_table[] = { 69 {0x0000, "LANCE 7990", /* Ancient lance chip. */ 70 LANCE_MUST_PAD + LANCE_MUST_UNRESET}, 71 {0x0003, "PCnet/ISA 79C960", /* 79C960 PCnet/ISA. */ 72 LANCE_ENABLE_AUTOSELECT}, 73 {0x2260, "PCnet/ISA+ 79C961", /* 79C961 PCnet/ISA+, Plug-n-Play. */ 74 LANCE_ENABLE_AUTOSELECT}, 75 {0x2420, "PCnet/PCI 79C970", /* 79C970 or 79C974 PCnet-SCSI, PCI. */ 76 LANCE_ENABLE_AUTOSELECT}, 77 {0x2430, "PCnet32", /* 79C965 PCnet for VL bus. */ 78 LANCE_ENABLE_AUTOSELECT}, 79 {0x2621, "PCnet/PCI-II 79C970A", /* 79C970A PCInetPCI II. */ 80 LANCE_ENABLE_AUTOSELECT}, 81 {0x2625, "PCnet-FAST III 79C973",/* 79C973 PCInet-FAST III. */ 82 LANCE_ENABLE_AUTOSELECT}, 83 {0x2626, "PCnet/HomePNA 79C978", 84 LANCE_ENABLE_AUTOSELECT|LANCE_SELECT_PHONELINE}, 85 {0x0, "PCnet (unknown)", 86 LANCE_ENABLE_AUTOSELECT}, 87 }; 88 89 /* ############## for LANCE device ############## */ 90 #define LANCE_ETH_ADDR 0x0 91 #define LANCE_DATA 0x10 92 #define LANCE_ADDR 0x12 93 #define LANCE_RESET 0x14 94 #define LANCE_BUS_IF 0x16 95 #define LANCE_TOTAL_SIZE 0x18 96 97 /* Use 2^4=16 {Rx,Tx} buffers */ 98 #define LANCE_LOG_RX_BUFFERS 4 99 #define RX_RING_SIZE (1 << (LANCE_LOG_RX_BUFFERS)) 100 #define RX_RING_MOD_MASK (RX_RING_SIZE - 1) 101 #define RX_RING_LEN_BITS ((LANCE_LOG_RX_BUFFERS) << 29) 102 103 #define LANCE_LOG_TX_BUFFERS 4 104 #define TX_RING_SIZE (1 << (LANCE_LOG_TX_BUFFERS)) 105 #define TX_RING_MOD_MASK (TX_RING_SIZE - 1) 106 #define TX_RING_LEN_BITS ((LANCE_LOG_TX_BUFFERS) << 29) 107 108 /* for lance_interface */ 109 struct lance_init_block 110 { 111 unsigned short mode; 112 unsigned char phys_addr[6]; 113 unsigned long filter[2]; 114 Address rx_ring; 115 Address tx_ring; 116 }; 117 118 struct lance_rx_head 119 { 120 union { 121 Address base; 122 unsigned char addr[4]; 123 } u; 124 short buf_length; /* 2s complement */ 125 short msg_length; 126 }; 127 128 struct lance_tx_head 129 { 130 union { 131 Address base; 132 unsigned char addr[4]; 133 } u; 134 short buf_length; /* 2s complement */ 135 short misc; 136 }; 137 138 struct lance_interface 139 { 140 struct lance_init_block init_block; 141 struct lance_rx_head rx_ring[RX_RING_SIZE]; 142 struct lance_tx_head tx_ring[TX_RING_SIZE]; 143 unsigned char rbuf[RX_RING_SIZE][ETH_FRAME_LEN]; 144 unsigned char tbuf[TX_RING_SIZE][ETH_FRAME_LEN]; 145 }; 146 147 /* =============== global variables =============== */ 148 /* AKA the stuff that really should have been in ether_card_t */ 149 static struct lance_interface *lp; 150 #define LANCE_BUF_SIZE (sizeof(struct lance_interface)) 151 static char *lance_buf = NULL; 152 static int rx_slot_nr = 0; /* Rx-slot number */ 153 static int tx_slot_nr = 0; /* Tx-slot number */ 154 static int cur_tx_slot_nr = 0; /* Tx-slot number */ 155 static phys_bytes tx_ring_base[TX_RING_SIZE]; /* Tx-slot physical address */ 156 static char isstored[TX_RING_SIZE]; /* Tx-slot in-use */ 157 158 static const struct netdriver lance_table = { 159 .ndr_name = "le", 160 .ndr_init = do_init, 161 .ndr_stop = do_stop, 162 .ndr_set_mode = do_set_mode, 163 .ndr_recv = do_recv, 164 .ndr_send = do_send, 165 .ndr_intr = do_intr, 166 .ndr_other = do_other, 167 }; 168 169 /*===========================================================================* 170 * main * 171 *===========================================================================*/ 172 int main(int argc, char **argv) 173 { 174 175 env_setargs(argc, argv); 176 177 netdriver_task(&lance_table); 178 179 return 0; 180 } 181 182 /*===========================================================================* 183 * lance_dump * 184 *===========================================================================*/ 185 static void lance_dump() 186 { 187 ether_card_t *ec; 188 int isr, csr; 189 unsigned short ioaddr; 190 191 printf("\n"); 192 ec = &ec_state; 193 194 printf("lance driver %s:\n", netdriver_name()); 195 196 ioaddr = ec->ec_port; 197 isr = read_csr(ioaddr, LANCE_CSR0); 198 printf("isr = 0x%x, mode = 0x%x\n", isr, ec->ec_mode); 199 200 printf("irq = %d\tioadr = 0x%x\n", ec->ec_irq, ec->ec_port); 201 202 csr = read_csr(ioaddr, LANCE_CSR0); 203 printf("CSR0: 0x%x\n", csr); 204 csr = read_csr(ioaddr, LANCE_CSR3); 205 printf("CSR3: 0x%x\n", csr); 206 csr = read_csr(ioaddr, LANCE_CSR4); 207 printf("CSR4: 0x%x\n", csr); 208 csr = read_csr(ioaddr, LANCE_CSR5); 209 printf("CSR5: 0x%x\n", csr); 210 csr = read_csr(ioaddr, LANCE_CSR15); 211 printf("CSR15: 0x%x\n", csr); 212 } 213 214 /*===========================================================================* 215 * do_other * 216 *===========================================================================*/ 217 static void do_other(const message *m_ptr, int ipc_status) 218 { 219 220 if (is_ipc_notify(ipc_status) && m_ptr->m_source == TTY_PROC_NR) 221 lance_dump(); 222 } 223 224 /*===========================================================================* 225 * ec_confaddr * 226 *===========================================================================*/ 227 static void ec_confaddr(netdriver_addr_t *addr, unsigned int instance) 228 { 229 int i; 230 char eakey[16]; 231 static char eafmt[]= "x:x:x:x:x:x"; 232 long v; 233 234 /* User defined ethernet address? */ 235 strlcpy(eakey, "LANCE0_EA", sizeof(eakey)); 236 eakey[5] += instance; 237 238 for (i = 0; i < 6; i++) 239 { 240 v= addr->na_addr[i]; 241 if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET) 242 break; 243 addr->na_addr[i]= v; 244 } 245 246 if (i != 0 && i != 6) 247 { 248 /* It's all or nothing; force a panic. */ 249 panic("invalid ethernet address supplied"); 250 } 251 } 252 253 /*===========================================================================* 254 * do_init * 255 *===========================================================================*/ 256 static int do_init(unsigned int instance, netdriver_addr_t *addr, 257 uint32_t *caps, unsigned int *ticks __unused) 258 { 259 /* Initialize the lance driver. */ 260 ether_card_t *ec; 261 #if VERBOSE 262 int i; 263 #endif 264 #if LANCE_FKEY 265 int r, fkeys, sfkeys; 266 #endif 267 268 #if LANCE_FKEY 269 fkeys = sfkeys = 0; 270 bit_set( sfkeys, 7 ); 271 if ( (r = fkey_map(&fkeys, &sfkeys)) != OK ) 272 printf("Warning: lance couldn't observe Shift+F7 key: %d\n",r); 273 #endif 274 275 /* Initialize the driver state. */ 276 ec= &ec_state; 277 memset(ec, 0, sizeof(*ec)); 278 279 /* See if there is a matching card. */ 280 if (!lance_probe(ec, instance)) 281 return ENXIO; 282 283 /* Initialize the hardware. */ 284 lance_init_hw(ec, addr, instance); 285 286 #if VERBOSE 287 printf("%s: Ethernet address ", netdriver_name()); 288 for (i= 0; i < 6; i++) 289 printf("%x%c", addr->na_addr[i], i < 5 ? ':' : '\n'); 290 #endif 291 292 *caps = NDEV_CAP_MCAST | NDEV_CAP_BCAST; 293 return OK; 294 } 295 296 /*===========================================================================* 297 * ec_reinit * 298 *===========================================================================*/ 299 static void ec_reinit(ether_card_t *ec) 300 { 301 spin_t spin; 302 int i; 303 unsigned short ioaddr = ec->ec_port; 304 305 /* stop */ 306 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STOP); 307 /* init */ 308 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_INIT); 309 /* poll for IDON */ 310 SPIN_FOR(&spin, 1000) { 311 if (read_csr(ioaddr, LANCE_CSR0) & LANCE_CSR0_IDON) 312 break; 313 } 314 315 /* Set 'Multicast Table' */ 316 for (i=0;i<4;++i) 317 { 318 write_csr(ioaddr, LANCE_CSR8 + i, 0xffff); 319 } 320 321 /* Set 'Receive Mode' */ 322 if (ec->ec_mode & NDEV_MODE_PROMISC) 323 { 324 write_csr(ioaddr, LANCE_CSR15, LANCE_CSR15_PROM); 325 } 326 else 327 { 328 if (ec->ec_mode & 329 (NDEV_MODE_BCAST | NDEV_MODE_MCAST_LIST | NDEV_MODE_MCAST_ALL)) 330 { 331 write_csr(ioaddr, LANCE_CSR15, 0x0000); 332 } 333 else 334 { 335 write_csr(ioaddr, LANCE_CSR15, LANCE_CSR15_DRCVBC); 336 } 337 } 338 339 /* purge Tx-ring */ 340 tx_slot_nr = cur_tx_slot_nr = 0; 341 for (i=0; i<TX_RING_SIZE; i++) 342 { 343 lp->tx_ring[i].u.base = 0; 344 isstored[i]=0; 345 } 346 cur_tx_slot_nr = tx_slot_nr; 347 348 /* re-init Rx-ring */ 349 rx_slot_nr = 0; 350 for (i=0; i<RX_RING_SIZE; i++) 351 { 352 lp->rx_ring[i].buf_length = -ETH_FRAME_LEN; 353 lp->rx_ring[i].u.addr[3] |= 0x80; 354 } 355 356 /* start && enable interrupt */ 357 write_csr(ioaddr, LANCE_CSR0, 358 LANCE_CSR0_IDON|LANCE_CSR0_IENA|LANCE_CSR0_STRT); 359 360 return; 361 } 362 363 /*===========================================================================* 364 * do_set_mode * 365 *===========================================================================*/ 366 static void do_set_mode(unsigned int mode, 367 const netdriver_addr_t *mcast_list __unused, 368 unsigned int mcast_count __unused) 369 { 370 ether_card_t *ec; 371 372 ec = &ec_state; 373 374 ec->ec_mode = mode; 375 376 ec_reinit(ec); 377 } 378 379 /*===========================================================================* 380 * do_intr * 381 *===========================================================================*/ 382 static void do_intr(unsigned int __unused mask) 383 { 384 ether_card_t *ec; 385 int must_restart = 0; 386 int r, check, status; 387 int isr = 0x0000; 388 unsigned short ioaddr; 389 390 ec = &ec_state; 391 ioaddr = ec->ec_port; 392 393 for (;;) 394 { 395 #if VERBOSE 396 printf("ETH: Reading ISR..."); 397 #endif 398 isr = read_csr(ioaddr, LANCE_CSR0); 399 if (isr & (LANCE_CSR0_ERR|LANCE_CSR0_RINT|LANCE_CSR0_TINT)) { 400 write_csr(ioaddr, LANCE_CSR0, 401 isr & ~(LANCE_CSR0_IENA|LANCE_CSR0_TDMD|LANCE_CSR0_STOP 402 |LANCE_CSR0_STRT|LANCE_CSR0_INIT) ); 403 } 404 write_csr(ioaddr, LANCE_CSR0, 405 LANCE_CSR0_BABL|LANCE_CSR0_CERR|LANCE_CSR0_MISS|LANCE_CSR0_MERR 406 |LANCE_CSR0_IDON|LANCE_CSR0_IENA); 407 408 if ((isr & (LANCE_CSR0_TINT|LANCE_CSR0_RINT|LANCE_CSR0_MISS 409 |LANCE_CSR0_BABL|LANCE_CSR0_ERR)) == 0x0000) 410 { 411 #if VERBOSE 412 printf("OK\n"); 413 #endif 414 break; 415 } 416 417 if (isr & LANCE_CSR0_MISS) 418 { 419 #if VERBOSE 420 printf("RX Missed Frame\n"); 421 #endif 422 netdriver_stat_ierror(1); 423 } 424 if ((isr & LANCE_CSR0_BABL) || (isr & LANCE_CSR0_TINT)) 425 { 426 if (isr & LANCE_CSR0_BABL) 427 { 428 #if VERBOSE 429 printf("TX Timeout\n"); 430 #endif 431 netdriver_stat_oerror(1); 432 } 433 if (isr & LANCE_CSR0_TINT) 434 { 435 #if VERBOSE 436 printf("TX INT\n"); 437 #endif 438 /* status check: restart if needed. */ 439 status = lp->tx_ring[cur_tx_slot_nr].u.base; 440 441 /* did an error (UFLO, LCOL, LCAR, RTRY) occur? */ 442 if (status & 0x40000000) 443 { 444 status = lp->tx_ring[cur_tx_slot_nr].misc; 445 netdriver_stat_oerror(1); 446 if (status & 0x4000) /* UFLO */ 447 { 448 must_restart=1; 449 } 450 } 451 else 452 { 453 if (status & 0x18000000) 454 netdriver_stat_coll(1); 455 } 456 } 457 /* transmit a packet on the next slot if it exists. */ 458 check = 0; 459 if (isstored[cur_tx_slot_nr]==1) 460 { 461 /* free the tx-slot just transmitted */ 462 isstored[cur_tx_slot_nr]=0; 463 cur_tx_slot_nr = (cur_tx_slot_nr + 1) & TX_RING_MOD_MASK; 464 465 /* next tx-slot is ready? */ 466 if (isstored[cur_tx_slot_nr]==1) 467 check=1; 468 else 469 check=0; 470 } 471 else 472 { 473 panic("got premature TX INT.."); 474 } 475 if (check==1) 476 { 477 lp->tx_ring[cur_tx_slot_nr].u.addr[3] = 0x83; 478 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_IENA|LANCE_CSR0_TDMD); 479 } 480 /* we set a buffered message in the slot if it exists. */ 481 /* and transmit it, if needed. */ 482 if (!must_restart) 483 netdriver_send(); 484 } 485 if (isr & LANCE_CSR0_RINT) 486 { 487 #if VERBOSE 488 printf("RX INT\n"); 489 #endif 490 netdriver_recv(); 491 } 492 493 if (must_restart == 1) 494 { 495 #if VERBOSE 496 printf("ETH: restarting...\n"); 497 #endif 498 499 ec_reinit(ec); 500 501 /* store a buffered message on the slot if it exists */ 502 netdriver_send(); 503 } 504 } 505 506 /* reenable interrupts */ 507 if ((r = sys_irqenable(&ec->ec_hook)) != OK) 508 panic("couldn't enable interrupt: %d", r); 509 } 510 511 /*===========================================================================* 512 * do_recv * 513 *===========================================================================*/ 514 static ssize_t do_recv(struct netdriver_data *data, size_t max) 515 { 516 ether_card_t *ec; 517 vir_bytes length; 518 int packet_processed; 519 int status; 520 unsigned short ioaddr; 521 522 ec = &ec_state; 523 ioaddr = ec->ec_port; 524 525 /* we check all the received slots until find a properly received packet */ 526 packet_processed = FALSE; 527 while (!packet_processed) 528 { 529 status = lp->rx_ring[rx_slot_nr].u.base >> 24; 530 531 /* is the slot marked as ready? */ 532 if ( (status & 0x80) != 0x00 ) 533 return SUSPEND; /* no */ 534 535 /* did an error occur? */ 536 if (status != 0x03) 537 { 538 if (status & 0x01) 539 netdriver_stat_ierror(1); 540 length = 0; 541 } 542 else 543 { 544 length = lp->rx_ring[rx_slot_nr].msg_length; 545 } 546 547 /* do we now have a valid packet? */ 548 if (length > 0) 549 { 550 if (length > max) 551 length = max; 552 netdriver_copyout(data, 0, lp->rbuf[rx_slot_nr], length); 553 packet_processed = TRUE; 554 } 555 556 /* set up this slot again, and we move to the next slot */ 557 lp->rx_ring[rx_slot_nr].buf_length = -ETH_FRAME_LEN; 558 lp->rx_ring[rx_slot_nr].u.addr[3] |= 0x80; 559 560 write_csr(ioaddr, LANCE_CSR0, 561 LANCE_CSR0_BABL|LANCE_CSR0_CERR|LANCE_CSR0_MISS 562 |LANCE_CSR0_MERR|LANCE_CSR0_IDON|LANCE_CSR0_IENA); 563 564 rx_slot_nr = (rx_slot_nr + 1) & RX_RING_MOD_MASK; 565 } 566 567 /* return the length of the packet we have received */ 568 return length; 569 } 570 571 /*===========================================================================* 572 * do_send * 573 *===========================================================================*/ 574 static int do_send(struct netdriver_data *data, size_t size) 575 { 576 int check; 577 ether_card_t *ec; 578 unsigned short ioaddr; 579 580 ec = &ec_state; 581 582 /* if all slots are used, this request must be deferred */ 583 if (isstored[tx_slot_nr]==1) 584 return SUSPEND; 585 586 /* copy the packet to the slot on DMA address */ 587 netdriver_copyin(data, 0, lp->tbuf[tx_slot_nr], size); 588 589 /* set-up for transmitting, and transmit it if needed. */ 590 lp->tx_ring[tx_slot_nr].buf_length = -size; 591 lp->tx_ring[tx_slot_nr].misc = 0x0; 592 lp->tx_ring[tx_slot_nr].u.base = tx_ring_base[tx_slot_nr]; 593 isstored[tx_slot_nr]=1; 594 if (cur_tx_slot_nr == tx_slot_nr) 595 check=1; 596 else 597 check=0; 598 tx_slot_nr = (tx_slot_nr + 1) & TX_RING_MOD_MASK; 599 600 if (check == 1) 601 { 602 ioaddr = ec->ec_port; 603 lp->tx_ring[cur_tx_slot_nr].u.addr[3] = 0x83; 604 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_IENA|LANCE_CSR0_TDMD); 605 } 606 607 return OK; 608 } 609 610 /*===========================================================================* 611 * do_stop * 612 *===========================================================================*/ 613 static void do_stop(void) 614 { 615 ether_card_t *ec; 616 unsigned short ioaddr; 617 618 ec = &ec_state; 619 620 ioaddr = ec->ec_port; 621 622 /* stop */ 623 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STOP); 624 625 /* Reset */ 626 in_word(ioaddr+LANCE_RESET); 627 } 628 629 /*===========================================================================* 630 * get_addressing * 631 *===========================================================================*/ 632 static void get_addressing(int devind, ether_card_t *ec) 633 { 634 unsigned int ioaddr; 635 int reg, irq; 636 637 for (reg = PCI_BAR; reg <= PCI_BAR_6; reg += 4) 638 { 639 ioaddr = pci_attr_r32(devind, reg); 640 641 if ((ioaddr & PCI_BAR_IO_MASK) == 0 || (ioaddr & PCI_BAR_IO) == 0) 642 continue; 643 /* Strip the I/O address out of the returned value */ 644 ioaddr &= PCI_BAR_IO_MASK; 645 ec->ec_port = ioaddr; 646 } 647 648 /* KK: Get the IRQ number */ 649 irq = pci_attr_r8(devind, PCI_IPR); 650 if (irq) 651 irq = pci_attr_r8(devind, PCI_ILR); 652 ec->ec_irq = irq; 653 } 654 655 /*===========================================================================* 656 * lance_probe * 657 *===========================================================================*/ 658 static int lance_probe(ether_card_t *ec, unsigned int skip) 659 { 660 unsigned short pci_cmd; 661 unsigned short ioaddr; 662 int lance_version, chip_version; 663 int devind, r; 664 u16_t vid, did; 665 666 pci_init(); 667 668 r= pci_first_dev(&devind, &vid, &did); 669 if (r == 0) 670 return 0; 671 672 while (skip--) 673 { 674 r= pci_next_dev(&devind, &vid, &did); 675 if (!r) 676 return 0; 677 } 678 679 pci_reserve(devind); 680 681 get_addressing(devind, ec); 682 683 /* ===== Bus Master ? ===== */ 684 pci_cmd = pci_attr_r32(devind, PCI_CR); 685 if (!(pci_cmd & PCI_CR_MAST_EN)) { 686 pci_cmd |= PCI_CR_MAST_EN; 687 pci_attr_w32(devind, PCI_CR, pci_cmd); 688 } 689 690 /* ===== Probe Details ===== */ 691 ioaddr = ec->ec_port; 692 693 /* Reset */ 694 in_word(ioaddr+LANCE_RESET); 695 696 if (read_csr(ioaddr, LANCE_CSR0) != LANCE_CSR0_STOP) 697 { 698 return 0; 699 } 700 701 /* Probe Chip Version */ 702 out_word(ioaddr+LANCE_ADDR, 88); /* Get the version of the chip */ 703 if (in_word(ioaddr+LANCE_ADDR) != 88) 704 lance_version = 0; 705 else 706 { 707 chip_version = read_csr(ioaddr, LANCE_CSR88); 708 chip_version |= read_csr(ioaddr, LANCE_CSR89) << 16; 709 710 if ((chip_version & 0xfff) != 0x3) 711 { 712 return 0; 713 } 714 chip_version = (chip_version >> 12) & 0xffff; 715 for (lance_version = 1; chip_table[lance_version].id_number != 0; 716 ++lance_version) 717 if (chip_table[lance_version].id_number == chip_version) 718 break; 719 } 720 721 #if VERBOSE 722 printf("%s: %s at %X:%d\n", 723 netdriver_name(), chip_table[lance_version].name, 724 ec->ec_port, ec->ec_irq); 725 #endif 726 727 return lance_version; 728 } 729 730 /*===========================================================================* 731 * virt_to_bus * 732 *===========================================================================*/ 733 static phys_bytes virt_to_bus(void *ptr) 734 { 735 phys_bytes value; 736 int r; 737 738 if ((r = sys_umap(SELF, VM_D, (vir_bytes)ptr, 4, &value)) != OK) 739 panic("sys_umap failed: %d", r); 740 741 return value; 742 } 743 744 /*===========================================================================* 745 * lance_init_hw * 746 *===========================================================================*/ 747 static void lance_init_hw(ether_card_t *ec, netdriver_addr_t *addr, 748 unsigned int instance) 749 { 750 phys_bytes lance_buf_phys; 751 int i, r; 752 Address l; 753 unsigned short ioaddr = ec->ec_port; 754 755 /* ============= setup init_block(cf. lance_probe1) ================ */ 756 /* make sure data structure is 8-byte aligned and below 16MB (for DMA) */ 757 758 /* Allocate memory */ 759 if ((lance_buf = alloc_contig(LANCE_BUF_SIZE, AC_ALIGN4K|AC_LOWER16M, 760 &lance_buf_phys)) == NULL) 761 panic("alloc_contig failed: %d", LANCE_BUF_SIZE); 762 763 l = (vir_bytes)lance_buf; 764 lp = (struct lance_interface *)l; 765 766 /* disable Tx and Rx */ 767 lp->init_block.mode = LANCE_CSR15_DTX|LANCE_CSR15_DRX; 768 lp->init_block.filter[0] = lp->init_block.filter[1] = 0x0; 769 /* using multiple Rx/Tx buffer */ 770 lp->init_block.rx_ring 771 = (virt_to_bus(&lp->rx_ring) & 0xffffff) | RX_RING_LEN_BITS; 772 lp->init_block.tx_ring 773 = (virt_to_bus(&lp->tx_ring) & 0xffffff) | TX_RING_LEN_BITS; 774 775 l = virt_to_bus(&lp->init_block); 776 write_csr(ioaddr, LANCE_CSR1, (unsigned short)l); 777 write_csr(ioaddr, LANCE_CSR2, (unsigned short)(l >> 16)); 778 write_csr(ioaddr, LANCE_CSR4, 779 LANCE_CSR4_APAD_XMT|LANCE_CSR4_MFCOM|LANCE_CSR4_RCVCCOM 780 |LANCE_CSR4_TXSTRTM|LANCE_CSR4_JABM); 781 782 /* ============= Get MAC address (cf. lance_probe1) ================ */ 783 for (i = 0; i < 6; ++i) 784 addr->na_addr[i]=in_byte(ioaddr+LANCE_ETH_ADDR+i); 785 786 /* Allow the user to override the hardware address. */ 787 ec_confaddr(addr, instance); 788 789 /* ============ (re)start init_block(cf. lance_reset) =============== */ 790 /* Reset the LANCE */ 791 (void)in_word(ioaddr+LANCE_RESET); 792 793 /* ----- Re-initialize the LANCE ----- */ 794 /* Set station address */ 795 for (i = 0; i < 6; ++i) 796 lp->init_block.phys_addr[i] = addr->na_addr[i]; 797 /* Preset the receive ring headers */ 798 for (i=0; i<RX_RING_SIZE; i++) 799 { 800 lp->rx_ring[i].buf_length = -ETH_FRAME_LEN; 801 /* OWN */ 802 lp->rx_ring[i].u.base = virt_to_bus(lp->rbuf[i]) & 0xffffff; 803 /* we set the top byte as the very last thing */ 804 lp->rx_ring[i].u.addr[3] = 0x80; 805 } 806 /* Preset the transmitting ring headers */ 807 for (i=0; i<TX_RING_SIZE; i++) 808 { 809 lp->tx_ring[i].u.base = 0; 810 tx_ring_base[i] = virt_to_bus(lp->tbuf[i]) & 0xffffff; 811 isstored[i] = 0; 812 } 813 /* enable Rx and Tx */ 814 lp->init_block.mode = 0x0; 815 816 l = (Address)virt_to_bus(&lp->init_block); 817 write_csr(ioaddr, LANCE_CSR1, (short)l); 818 write_csr(ioaddr, LANCE_CSR2, (short)(l >> 16)); 819 write_csr(ioaddr, LANCE_CSR4, 820 LANCE_CSR4_APAD_XMT|LANCE_CSR4_MFCOM|LANCE_CSR4_RCVCCOM 821 |LANCE_CSR4_TXSTRTM|LANCE_CSR4_JABM); 822 823 /* ----- start when init done. ----- */ 824 ec_reinit(ec); 825 826 /* Set the interrupt handler */ 827 ec->ec_hook = ec->ec_irq; 828 if ((r=sys_irqsetpolicy(ec->ec_irq, 0, &ec->ec_hook)) != OK) 829 panic("couldn't set IRQ policy: %d", r); 830 if ((r = sys_irqenable(&ec->ec_hook)) != OK) 831 panic("couldn't enable interrupt: %d", r); 832 833 /* start && enable interrupt */ 834 write_csr(ioaddr, LANCE_CSR0, 835 LANCE_CSR0_IDON|LANCE_CSR0_IENA|LANCE_CSR0_STRT); 836 } 837 838 /*===========================================================================* 839 * in_byte * 840 *===========================================================================*/ 841 static u8_t in_byte(port_t port) 842 { 843 int r; 844 u32_t value; 845 846 r= sys_inb(port, &value); 847 if (r != OK) 848 panic("sys_inb failed: %d", r); 849 return value; 850 } 851 852 /*===========================================================================* 853 * in_word * 854 *===========================================================================*/ 855 static u16_t in_word(port_t port) 856 { 857 int r; 858 u32_t value; 859 860 r= sys_inw(port, &value); 861 if (r != OK) 862 panic("sys_inw failed: %d", r); 863 return value; 864 } 865 866 867 /*===========================================================================* 868 * out_word * 869 *===========================================================================*/ 870 static void out_word(port_t port, u16_t value) 871 { 872 int r; 873 874 r= sys_outw(port, value); 875 if (r != OK) 876 panic("sys_outw failed: %d", r); 877 } 878 879 /*===========================================================================* 880 * read_csr * 881 *===========================================================================*/ 882 static u16_t read_csr(port_t ioaddr, u16_t csrno) 883 { 884 out_word(ioaddr+LANCE_ADDR, csrno); 885 return in_word(ioaddr+LANCE_DATA); 886 } 887 888 /*===========================================================================* 889 * write_csr * 890 *===========================================================================*/ 891 static void write_csr(port_t ioaddr, u16_t csrno, u16_t value) 892 { 893 out_word(ioaddr+LANCE_ADDR, csrno); 894 out_word(ioaddr+LANCE_DATA, value); 895 } 896