1 /* 2 * lance.c 3 * 4 * This file contains a ethernet device driver for AMD LANCE based ethernet 5 * cards. 6 * 7 * The valid messages and their parameters are: 8 * 9 * m_type DL_COUNT DL_MODE DL_GRANT 10 * |--------------+----------+---------+---------| 11 * | DL_WRITEV_S | count | | grant | 12 * |--------------|----------|---------|---------| 13 * | DL_READV_S | count | | grant | 14 * |--------------|----------|---------|---------| 15 * | DL_CONF | | mode | | 16 * |--------------|----------|---------|---------| 17 * | DL_GETSTAT_S | | | grant | 18 * |--------------|----------|---------|---------| 19 * | hardware int | | | | 20 * |--------------|----------|---------|---------| 21 * 22 * The messages sent are: 23 * 24 * m_type DL_COUNT DL_FLAGS 25 * |---------------+----------+---------| 26 * | DL_TASK_REPLY | rd-count | flags | 27 * |---------------|----------|---------| 28 * 29 * m_type 30 * |---------------| 31 * | DL_STAT_REPLY | 32 * |---------------| 33 * 34 * m_type DL_STAT DL_ADDR 35 * |---------------+---------+---------------| 36 * | DL_CONF_REPLY | code | ethernet addr | 37 * |---------------|---------|---------------| 38 * 39 * Created: Jul 27, 2002 by Kazuya Kodama <kazuya@nii.ac.jp> 40 * Adapted for Minix 3: Sep 05, 2005 by Joren l'Ami <jwlami@cs.vu.nl> 41 */ 42 43 #define VERBOSE 0 /* Verbose debugging output */ 44 #define LANCE_FKEY 0 /* Use function key to dump Lance stats */ 45 46 #include <minix/drivers.h> 47 #include <minix/netdriver.h> 48 49 #include <net/hton.h> 50 #include <net/gen/ether.h> 51 #include <net/gen/eth_io.h> 52 #include <assert.h> 53 54 #include <minix/syslib.h> 55 #include <minix/endpoint.h> 56 #include <machine/pci.h> 57 #include <minix/ds.h> 58 59 #include "lance.h" 60 61 static ether_card_t ec_state; 62 static int ec_instance; 63 64 /* Configuration */ 65 typedef struct ec_conf 66 { 67 port_t ec_port; 68 int ec_irq; 69 phys_bytes ec_mem; 70 } ec_conf_t; 71 72 /* We hardly use these. Just "LANCE0=on/off" "LANCE1=on/off" mean. */ 73 #define EC_CONF_NR 3 74 ec_conf_t ec_conf[EC_CONF_NR]= /* Card addresses */ 75 { 76 /* I/O port, IRQ, Buffer address. */ 77 { 0x1000, 9, 0x00000, }, 78 { 0xD000, 15, 0x00000, }, 79 { 0x0000, 0, 0x00000, }, 80 }; 81 82 /* General */ 83 static void do_init(message *mp); 84 static void ec_init(ether_card_t *ec); 85 static void ec_confaddr(ether_card_t *ec); 86 static void ec_reinit(ether_card_t *ec); 87 static void ec_check_ints(ether_card_t *ec); 88 static void conf_hw(ether_card_t *ec); 89 static void update_conf(ether_card_t *ec, ec_conf_t *ecp); 90 static void mess_reply(message *req, message *reply); 91 static void do_int(ether_card_t *ec); 92 static void reply(ether_card_t *ec); 93 static void ec_reset(ether_card_t *ec); 94 static void ec_send(ether_card_t *ec); 95 static void ec_recv(ether_card_t *ec); 96 static void do_vwrite_s(message *mp, int from_int); 97 static void do_vread_s(const message *mp); 98 static void ec_user2nic(ether_card_t *dep, iovec_dat_t *iovp, vir_bytes 99 offset, int nic_addr, vir_bytes count); 100 static void ec_nic2user(ether_card_t *ec, int nic_addr, iovec_dat_t 101 *iovp, vir_bytes offset, vir_bytes count); 102 static int calc_iovec_size(iovec_dat_t *iovp); 103 static void ec_next_iovec(iovec_dat_t *iovp); 104 static void do_getstat_s(message *mp); 105 static void lance_stop(ether_card_t *ec); 106 107 static void lance_dump(void); 108 static void getAddressing(int devind, ether_card_t *ec); 109 110 /* probe+init LANCE cards */ 111 static int lance_probe(ether_card_t *ec, int skip); 112 static void lance_init_card(ether_card_t *ec); 113 114 /* Accesses Lance Control and Status Registers */ 115 static u8_t in_byte(port_t port); 116 static u16_t in_word(port_t port); 117 static void out_word(port_t port, u16_t value); 118 static u16_t read_csr(port_t ioaddr, u16_t csrno); 119 static void write_csr(port_t ioaddr, u16_t csrno, u16_t value); 120 121 /* --- LANCE --- */ 122 /* General */ 123 typedef unsigned long Address; 124 125 #define virt_to_bus(x) (vir2phys((unsigned long)x)) 126 unsigned long vir2phys( unsigned long x ) 127 { 128 int r; 129 unsigned long value; 130 131 if ( (r=sys_umap( SELF, VM_D, x, 4, &value )) != OK ) { 132 printf("lance: umap of 0x%lx failed\n",x ); 133 panic("sys_umap failed: %d", r); 134 } 135 136 return value; 137 } 138 139 /* DMA limitations */ 140 #define DMA_ADDR_MASK 0xFFFFFF /* mask to verify DMA address is 24-bit */ 141 142 #define CORRECT_DMA_MEM() ( (virt_to_bus(lance_buf + sizeof(struct lance_interface)) & ~DMA_ADDR_MASK) == 0 ) 143 144 #define ETH_FRAME_LEN 1518 145 146 #define LANCE_MUST_PAD 0x00000001 147 #define LANCE_ENABLE_AUTOSELECT 0x00000002 148 #define LANCE_SELECT_PHONELINE 0x00000004 149 #define LANCE_MUST_UNRESET 0x00000008 150 151 static const struct lance_chip_type 152 { 153 int id_number; 154 const char *name; 155 int flags; 156 } chip_table[] = { 157 {0x0000, "LANCE 7990", /* Ancient lance chip. */ 158 LANCE_MUST_PAD + LANCE_MUST_UNRESET}, 159 {0x0003, "PCnet/ISA 79C960", /* 79C960 PCnet/ISA. */ 160 LANCE_ENABLE_AUTOSELECT}, 161 {0x2260, "PCnet/ISA+ 79C961", /* 79C961 PCnet/ISA+, Plug-n-Play. */ 162 LANCE_ENABLE_AUTOSELECT}, 163 {0x2420, "PCnet/PCI 79C970", /* 79C970 or 79C974 PCnet-SCSI, PCI. */ 164 LANCE_ENABLE_AUTOSELECT}, 165 {0x2430, "PCnet32", /* 79C965 PCnet for VL bus. */ 166 LANCE_ENABLE_AUTOSELECT}, 167 {0x2621, "PCnet/PCI-II 79C970A", /* 79C970A PCInetPCI II. */ 168 LANCE_ENABLE_AUTOSELECT}, 169 {0x2625, "PCnet-FAST III 79C973",/* 79C973 PCInet-FAST III. */ 170 LANCE_ENABLE_AUTOSELECT}, 171 {0x2626, "PCnet/HomePNA 79C978", 172 LANCE_ENABLE_AUTOSELECT|LANCE_SELECT_PHONELINE}, 173 {0x0, "PCnet (unknown)", 174 LANCE_ENABLE_AUTOSELECT}, 175 }; 176 177 /* ############## for LANCE device ############## */ 178 #define LANCE_ETH_ADDR 0x0 179 #define LANCE_DATA 0x10 180 #define LANCE_ADDR 0x12 181 #define LANCE_RESET 0x14 182 #define LANCE_BUS_IF 0x16 183 #define LANCE_TOTAL_SIZE 0x18 184 185 /* Use 2^4=16 {Rx,Tx} buffers */ 186 #define LANCE_LOG_RX_BUFFERS 4 187 #define RX_RING_SIZE (1 << (LANCE_LOG_RX_BUFFERS)) 188 #define RX_RING_MOD_MASK (RX_RING_SIZE - 1) 189 #define RX_RING_LEN_BITS ((LANCE_LOG_RX_BUFFERS) << 29) 190 191 #define LANCE_LOG_TX_BUFFERS 4 192 #define TX_RING_SIZE (1 << (LANCE_LOG_TX_BUFFERS)) 193 #define TX_RING_MOD_MASK (TX_RING_SIZE - 1) 194 #define TX_RING_LEN_BITS ((LANCE_LOG_TX_BUFFERS) << 29) 195 196 /* for lance_interface */ 197 struct lance_init_block 198 { 199 unsigned short mode; 200 unsigned char phys_addr[6]; 201 unsigned long filter[2]; 202 Address rx_ring; 203 Address tx_ring; 204 }; 205 206 struct lance_rx_head 207 { 208 union { 209 Address base; 210 unsigned char addr[4]; 211 } u; 212 short buf_length; /* 2s complement */ 213 short msg_length; 214 }; 215 216 struct lance_tx_head 217 { 218 union { 219 Address base; 220 unsigned char addr[4]; 221 } u; 222 short buf_length; /* 2s complement */ 223 short misc; 224 }; 225 226 struct lance_interface 227 { 228 struct lance_init_block init_block; 229 struct lance_rx_head rx_ring[RX_RING_SIZE]; 230 struct lance_tx_head tx_ring[TX_RING_SIZE]; 231 unsigned char rbuf[RX_RING_SIZE][ETH_FRAME_LEN]; 232 unsigned char tbuf[TX_RING_SIZE][ETH_FRAME_LEN]; 233 }; 234 235 /* =============== global variables =============== */ 236 /* AKA the stuff that really should have been in ether_card_t */ 237 static struct lance_interface *lp; 238 #define LANCE_BUF_SIZE (sizeof(struct lance_interface)) 239 static char *lance_buf = NULL; 240 static int rx_slot_nr = 0; /* Rx-slot number */ 241 static int tx_slot_nr = 0; /* Tx-slot number */ 242 static int cur_tx_slot_nr = 0; /* Tx-slot number */ 243 static char isstored[TX_RING_SIZE]; /* Tx-slot in-use */ 244 245 phys_bytes lance_buf_phys; 246 247 /* SEF functions and variables. */ 248 static void sef_local_startup(void); 249 static int sef_cb_init_fresh(int type, sef_init_info_t *info); 250 static void sef_cb_signal_handler(int signo); 251 252 /*===========================================================================* 253 * main * 254 *===========================================================================*/ 255 int main( int argc, char **argv ) 256 { 257 message m; 258 int ipc_status; 259 int r; 260 ether_card_t *ec; 261 262 /* SEF local startup. */ 263 env_setargs(argc, argv); 264 sef_local_startup(); 265 266 ec= &ec_state; 267 268 while (TRUE) 269 { 270 if (ec->ec_irq != 0) 271 sys_irqenable(&ec->ec_hook); 272 273 if ((r= netdriver_receive(ANY, &m, &ipc_status)) != OK) 274 panic("netdriver_receive failed: %d", r); 275 276 if (ec->ec_irq != 0) 277 sys_irqdisable(&ec->ec_hook); 278 279 if (is_ipc_notify(ipc_status)) { 280 switch(_ENDPOINT_P(m.m_source)) { 281 case TTY_PROC_NR: 282 lance_dump(); 283 break; 284 case HARDWARE: 285 if (ec->mode == EC_ENABLED) 286 { 287 ec->ec_int_pending = 0; 288 ec_check_ints(ec); 289 do_int(ec); 290 } 291 break; 292 default: 293 panic("illegal notify source: %d", m.m_source); 294 } 295 296 /* get next message */ 297 continue; 298 } 299 300 switch (m.m_type) 301 { 302 case DL_WRITEV_S: 303 do_vwrite_s(&m, FALSE); 304 break; 305 case DL_READV_S: 306 do_vread_s(&m); 307 break; 308 case DL_CONF: 309 do_init(&m); 310 break; 311 case DL_GETSTAT_S: 312 do_getstat_s(&m); 313 break; 314 default: 315 panic("illegal message: %d", m.m_type); 316 } 317 } 318 319 return 0; 320 } 321 322 /*===========================================================================* 323 * sef_local_startup * 324 *===========================================================================*/ 325 static void sef_local_startup() 326 { 327 /* Register init callbacks. */ 328 sef_setcb_init_fresh(sef_cb_init_fresh); 329 sef_setcb_init_lu(sef_cb_init_fresh); 330 sef_setcb_init_restart(sef_cb_init_fresh); 331 332 /* Register live update callbacks. */ 333 sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready); 334 sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_workfree); 335 336 /* Register signal callbacks. */ 337 sef_setcb_signal_handler(sef_cb_signal_handler); 338 339 /* Let SEF perform startup. */ 340 sef_startup(); 341 } 342 343 /*===========================================================================* 344 * sef_cb_init_fresh * 345 *===========================================================================*/ 346 static int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) 347 { 348 /* Initialize the lance driver. */ 349 long v; 350 #if LANCE_FKEY 351 int r, fkeys, sfkeys; 352 #endif 353 354 #if LANCE_FKEY 355 fkeys = sfkeys = 0; 356 bit_set( sfkeys, 7 ); 357 if ( (r = fkey_map(&fkeys, &sfkeys)) != OK ) 358 printf("Warning: lance couldn't observe Shift+F7 key: %d\n",r); 359 #endif 360 361 v = 0; 362 (void) env_parse("instance", "d", 0, &v, 0, 255); 363 ec_instance = (int) v; 364 365 /* Announce we are up! */ 366 netdriver_announce(); 367 368 return OK; 369 } 370 371 /*===========================================================================* 372 * sef_cb_signal_handler * 373 *===========================================================================*/ 374 static void sef_cb_signal_handler(int signo) 375 { 376 377 /* Only check for termination signal, ignore anything else. */ 378 if (signo != SIGTERM) return; 379 380 if (ec_state.mode == EC_ENABLED) 381 lance_stop(&ec_state); 382 383 #if VERBOSE 384 printf("LANCE driver stopped.\n"); 385 #endif 386 387 exit(0); 388 } 389 390 /*===========================================================================* 391 * lance_dump * 392 *===========================================================================*/ 393 static void lance_dump() 394 { 395 ether_card_t *ec; 396 int isr, csr; 397 unsigned short ioaddr; 398 399 printf("\n"); 400 ec = &ec_state; 401 if (ec->mode == EC_DISABLED) 402 printf("lance instance %d is disabled\n", ec_instance); 403 else if (ec->mode == EC_SINK) 404 printf("lance instance %d is in sink mode\n", ec_instance); 405 406 if (ec->mode != EC_ENABLED) 407 return; 408 409 printf("lance statistics of instance %d:\n", ec_instance); 410 411 printf("recvErr :%8ld\t", ec->eth_stat.ets_recvErr); 412 printf("sendErr :%8ld\t", ec->eth_stat.ets_sendErr); 413 printf("OVW :%8ld\n", ec->eth_stat.ets_OVW); 414 415 printf("CRCerr :%8ld\t", ec->eth_stat.ets_CRCerr); 416 printf("frameAll :%8ld\t", ec->eth_stat.ets_frameAll); 417 printf("missedP :%8ld\n", ec->eth_stat.ets_missedP); 418 419 printf("packetR :%8ld\t", ec->eth_stat.ets_packetR); 420 printf("packetT :%8ld\t", ec->eth_stat.ets_packetT); 421 printf("transDef :%8ld\n", ec->eth_stat.ets_transDef); 422 423 printf("collision :%8ld\t", ec->eth_stat.ets_collision); 424 printf("transAb :%8ld\t", ec->eth_stat.ets_transAb); 425 printf("carrSense :%8ld\n", ec->eth_stat.ets_carrSense); 426 427 printf("fifoUnder :%8ld\t", ec->eth_stat.ets_fifoUnder); 428 printf("fifoOver :%8ld\t", ec->eth_stat.ets_fifoOver); 429 printf("CDheartbeat:%8ld\n", ec->eth_stat.ets_CDheartbeat); 430 431 printf("OWC :%8ld\t", ec->eth_stat.ets_OWC); 432 433 ioaddr = ec->ec_port; 434 isr = read_csr(ioaddr, LANCE_CSR0); 435 printf("isr = 0x%x, flags = 0x%x\n", isr, 436 ec->flags); 437 438 printf("irq = %d\tioadr = 0x%x\n", ec->ec_irq, ec->ec_port); 439 440 csr = read_csr(ioaddr, LANCE_CSR0); 441 printf("CSR0: 0x%x\n", csr); 442 csr = read_csr(ioaddr, LANCE_CSR3); 443 printf("CSR3: 0x%x\n", csr); 444 csr = read_csr(ioaddr, LANCE_CSR4); 445 printf("CSR4: 0x%x\n", csr); 446 csr = read_csr(ioaddr, LANCE_CSR5); 447 printf("CSR5: 0x%x\n", csr); 448 csr = read_csr(ioaddr, LANCE_CSR15); 449 printf("CSR15: 0x%x\n", csr); 450 } 451 452 /*===========================================================================* 453 * do_init * 454 *===========================================================================*/ 455 static void do_init(mp) 456 message *mp; 457 { 458 ether_card_t *ec; 459 message reply_mess; 460 461 pci_init(); 462 463 if(!lance_buf && !(lance_buf = alloc_contig(LANCE_BUF_SIZE, AC_ALIGN4K|AC_LOWER16M, &lance_buf_phys))) { 464 panic("alloc_contig failed: %d", LANCE_BUF_SIZE); 465 } 466 467 ec= &ec_state; 468 strlcpy(ec->port_name, "lance#0", sizeof(ec->port_name)); 469 ec->port_name[6] += ec_instance; 470 471 if (ec->mode == EC_DISABLED) 472 { 473 /* This is the default, try to (re)locate the device. */ 474 /* only try to enable if memory is correct for DMA */ 475 if ( CORRECT_DMA_MEM() ) 476 { 477 conf_hw(ec); 478 } 479 else 480 { 481 printf("LANCE: DMA denied because address out of range\n" ); 482 } 483 484 if (ec->mode == EC_DISABLED) 485 { 486 /* Probe failed, or the device is configured off. */ 487 reply_mess.m_type= DL_CONF_REPLY; 488 reply_mess.m_netdrv_net_dl_conf.stat = ENXIO; 489 mess_reply(mp, &reply_mess); 490 return; 491 } 492 if (ec->mode == EC_ENABLED) 493 ec_init(ec); 494 } 495 496 if (ec->mode == EC_SINK) 497 { 498 ec->mac_address.ea_addr[0] = 499 ec->mac_address.ea_addr[1] = 500 ec->mac_address.ea_addr[2] = 501 ec->mac_address.ea_addr[3] = 502 ec->mac_address.ea_addr[4] = 503 ec->mac_address.ea_addr[5] = 0; 504 ec_confaddr(ec); 505 reply_mess.m_type = DL_CONF_REPLY; 506 reply_mess.m_netdrv_net_dl_conf.stat = OK; 507 memcpy(reply_mess.m_netdrv_net_dl_conf.hw_addr, ec->mac_address.ea_addr, 508 sizeof(reply_mess.m_netdrv_net_dl_conf.hw_addr)); 509 mess_reply(mp, &reply_mess); 510 return; 511 } 512 assert(ec->mode == EC_ENABLED); 513 assert(ec->flags & ECF_ENABLED); 514 515 ec->flags &= ~(ECF_PROMISC | ECF_MULTI | ECF_BROAD); 516 517 if (mp->m_net_netdrv_dl_conf.mode & DL_PROMISC_REQ) 518 ec->flags |= ECF_PROMISC | ECF_MULTI | ECF_BROAD; 519 if (mp->m_net_netdrv_dl_conf.mode & DL_MULTI_REQ) 520 ec->flags |= ECF_MULTI; 521 if (mp->m_net_netdrv_dl_conf.mode & DL_BROAD_REQ) 522 ec->flags |= ECF_BROAD; 523 524 ec_reinit(ec); 525 526 reply_mess.m_type = DL_CONF_REPLY; 527 reply_mess.m_netdrv_net_dl_conf.stat = OK; 528 memcpy(reply_mess.m_netdrv_net_dl_conf.hw_addr, ec->mac_address.ea_addr, 529 sizeof(reply_mess.m_netdrv_net_dl_conf.hw_addr)); 530 531 mess_reply(mp, &reply_mess); 532 } 533 534 535 /*===========================================================================* 536 * do_int * 537 *===========================================================================*/ 538 static void do_int(ec) 539 ether_card_t *ec; 540 { 541 if (ec->flags & (ECF_PACK_SEND | ECF_PACK_RECV)) 542 reply(ec); 543 } 544 545 546 /*===========================================================================* 547 * conf_hw * 548 *===========================================================================*/ 549 static void conf_hw(ec) 550 ether_card_t *ec; 551 { 552 static eth_stat_t empty_stat = {0, 0, 0, 0, 0, 0 /* ,... */ }; 553 554 int confnr; 555 ec_conf_t *ecp; 556 557 ec->mode= EC_DISABLED; /* Superfluous */ 558 559 /* Pick a default configuration. This hardly matters anymore. */ 560 confnr= MIN(ec_instance, EC_CONF_NR-1); 561 562 ecp= &ec_conf[confnr]; 563 update_conf(ec, ecp); 564 if (ec->mode != EC_ENABLED) 565 return; 566 567 if (!lance_probe(ec, ec_instance)) 568 { 569 printf("%s: No ethernet card found on PCI-BIOS info.\n", 570 ec->port_name); 571 ec->mode= EC_DISABLED; 572 return; 573 } 574 575 /* XXX */ if (ec->ec_linmem == 0) ec->ec_linmem= 0xFFFF0000; 576 577 ec->flags = ECF_EMPTY; 578 ec->eth_stat = empty_stat; 579 } 580 581 582 /*===========================================================================* 583 * update_conf * 584 *===========================================================================*/ 585 static void update_conf(ec, ecp) 586 ether_card_t *ec; 587 ec_conf_t *ecp; 588 { 589 long v; 590 char eckey[16]; 591 static char ec_fmt[] = "x:d:x:x"; 592 593 /* Get the default settings and modify them from the environment. */ 594 strlcpy(eckey, "LANCE0", sizeof(eckey)); 595 eckey[5] += ec_instance; 596 ec->mode= EC_SINK; 597 v= ecp->ec_port; 598 switch (env_parse(eckey, ec_fmt, 0, &v, 0x0000L, 0xFFFFL)) 599 { 600 case EP_OFF: 601 ec->mode= EC_DISABLED; 602 break; 603 case EP_ON: 604 case EP_SET: 605 default: 606 ec->mode= EC_ENABLED; /* Might become disabled if 607 * all probes fail */ 608 break; 609 } 610 611 ec->ec_port= v; 612 613 v= ecp->ec_irq | DEI_DEFAULT; 614 (void) env_parse(eckey, ec_fmt, 1, &v, 0L, (long) NR_IRQ_VECTORS - 1); 615 ec->ec_irq= v; 616 617 v= ecp->ec_mem; 618 (void) env_parse(eckey, ec_fmt, 2, &v, 0L, 0xFFFFFL); 619 ec->ec_linmem= v; 620 621 v= 0; 622 (void) env_parse(eckey, ec_fmt, 3, &v, 0x2000L, 0x8000L); 623 ec->ec_ramsize= v; 624 } 625 626 627 /*===========================================================================* 628 * ec_init * 629 *===========================================================================*/ 630 static void ec_init(ec) 631 ether_card_t *ec; 632 { 633 int r; 634 #if VERBOSE 635 int i; 636 #endif 637 638 /* General initialization */ 639 ec->flags = ECF_EMPTY; 640 lance_init_card(ec); /* Get mac_address, etc ...*/ 641 642 ec_confaddr(ec); 643 644 #if VERBOSE 645 printf("%s: Ethernet address ", ec->port_name); 646 for (i= 0; i < 6; i++) 647 printf("%x%c", ec->mac_address.ea_addr[i], 648 i < 5 ? ':' : '\n'); 649 #endif 650 651 /* Finish the initialization */ 652 ec->flags |= ECF_ENABLED; 653 654 /* Set the interrupt handler */ 655 ec->ec_hook = ec->ec_irq; 656 if ((r=sys_irqsetpolicy(ec->ec_irq, 0, &ec->ec_hook)) != OK) 657 printf("lance: error, couldn't set IRQ policy: %d\n", r); 658 659 return; 660 } 661 662 663 /*===========================================================================* 664 * reply * 665 *===========================================================================*/ 666 static void reply(ec) 667 ether_card_t *ec; 668 { 669 message reply; 670 int flags,r; 671 672 flags = DL_NOFLAGS; 673 if (ec->flags & ECF_PACK_SEND) 674 flags |= DL_PACK_SEND; 675 if (ec->flags & ECF_PACK_RECV) 676 flags |= DL_PACK_RECV; 677 678 reply.m_type = DL_TASK_REPLY; 679 reply.m_netdrv_net_dl_task.flags = flags; 680 reply.m_netdrv_net_dl_task.count = ec->read_s; 681 682 r = ipc_send(ec->client, &reply); 683 if (r < 0) 684 panic("ipc_send failed: %d", r); 685 686 ec->read_s = 0; 687 ec->flags &= ~(ECF_PACK_SEND | ECF_PACK_RECV); 688 } 689 690 691 /*===========================================================================* 692 * mess_reply * 693 *===========================================================================*/ 694 static void mess_reply(req, reply_mess) 695 message *req; 696 message *reply_mess; 697 { 698 if (ipc_send(req->m_source, reply_mess) != OK) 699 panic("unable to mess_reply"); 700 } 701 702 703 /*===========================================================================* 704 * ec_confaddr * 705 *===========================================================================*/ 706 static void ec_confaddr(ec) 707 ether_card_t *ec; 708 { 709 int i; 710 char eakey[16]; 711 static char eafmt[]= "x:x:x:x:x:x"; 712 long v; 713 714 /* User defined ethernet address? */ 715 strlcpy(eakey, "LANCE0_EA", sizeof(eakey)); 716 eakey[5] += ec_instance; 717 718 for (i = 0; i < 6; i++) 719 { 720 v= ec->mac_address.ea_addr[i]; 721 if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET) 722 break; 723 ec->mac_address.ea_addr[i]= v; 724 } 725 726 if (i != 0 && i != 6) 727 { 728 /* It's all or nothing; force a panic. */ 729 (void) env_parse(eakey, "?", 0, &v, 0L, 0L); 730 } 731 } 732 733 734 /*===========================================================================* 735 * ec_reinit * 736 *===========================================================================*/ 737 static void ec_reinit(ec) 738 ether_card_t *ec; 739 { 740 int i; 741 unsigned short ioaddr = ec->ec_port; 742 743 /* stop */ 744 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STOP); 745 746 /* purge Tx-ring */ 747 tx_slot_nr = cur_tx_slot_nr = 0; 748 for (i=0; i<TX_RING_SIZE; i++) 749 { 750 lp->tx_ring[i].u.base = 0; 751 isstored[i]=0; 752 } 753 754 /* re-init Rx-ring */ 755 rx_slot_nr = 0; 756 for (i=0; i<RX_RING_SIZE; i++) 757 { 758 lp->rx_ring[i].buf_length = -ETH_FRAME_LEN; 759 lp->rx_ring[i].u.addr[3] |= 0x80; 760 } 761 762 /* Set 'Receive Mode' */ 763 if (ec->flags & ECF_PROMISC) 764 { 765 write_csr(ioaddr, LANCE_CSR15, LANCE_CSR15_PROM); 766 } 767 else 768 { 769 if (ec->flags & (ECF_BROAD | ECF_MULTI)) 770 { 771 write_csr(ioaddr, LANCE_CSR15, 0x0000); 772 } 773 else 774 { 775 write_csr(ioaddr, LANCE_CSR15, LANCE_CSR15_DRCVBC); 776 } 777 } 778 779 /* start && enable interrupt */ 780 write_csr(ioaddr, LANCE_CSR0, 781 LANCE_CSR0_IDON|LANCE_CSR0_IENA|LANCE_CSR0_STRT); 782 783 return; 784 } 785 786 /*===========================================================================* 787 * ec_check_ints * 788 *===========================================================================*/ 789 static void ec_check_ints(ec) 790 ether_card_t *ec; 791 { 792 int must_restart = 0; 793 int check,status; 794 int isr = 0x0000; 795 unsigned short ioaddr = ec->ec_port; 796 797 if (!(ec->flags & ECF_ENABLED)) 798 panic("got premature interrupt"); 799 800 for (;;) 801 { 802 #if VERBOSE 803 printf("ETH: Reading ISR..."); 804 #endif 805 isr = read_csr(ioaddr, LANCE_CSR0); 806 if (isr & (LANCE_CSR0_ERR|LANCE_CSR0_RINT|LANCE_CSR0_TINT)) { 807 write_csr(ioaddr, LANCE_CSR0, 808 isr & ~(LANCE_CSR0_IENA|LANCE_CSR0_TDMD|LANCE_CSR0_STOP 809 |LANCE_CSR0_STRT|LANCE_CSR0_INIT) ); 810 } 811 write_csr(ioaddr, LANCE_CSR0, 812 LANCE_CSR0_BABL|LANCE_CSR0_CERR|LANCE_CSR0_MISS|LANCE_CSR0_MERR 813 |LANCE_CSR0_IDON|LANCE_CSR0_IENA); 814 815 #define ISR_RST 0x0000 816 817 if ((isr & (LANCE_CSR0_TINT|LANCE_CSR0_RINT|LANCE_CSR0_MISS 818 |LANCE_CSR0_BABL|LANCE_CSR0_ERR)) == 0x0000) 819 { 820 #if VERBOSE 821 printf("OK\n"); 822 #endif 823 break; 824 } 825 826 if (isr & LANCE_CSR0_MISS) 827 { 828 #if VERBOSE 829 printf("RX Missed Frame\n"); 830 #endif 831 ec->eth_stat.ets_recvErr++; 832 } 833 if ((isr & LANCE_CSR0_BABL) || (isr & LANCE_CSR0_TINT)) 834 { 835 if (isr & LANCE_CSR0_BABL) 836 { 837 #if VERBOSE 838 printf("TX Timeout\n"); 839 #endif 840 ec->eth_stat.ets_sendErr++; 841 } 842 if (isr & LANCE_CSR0_TINT) 843 { 844 #if VERBOSE 845 printf("TX INT\n"); 846 #endif 847 /* status check: restart if needed. */ 848 status = lp->tx_ring[cur_tx_slot_nr].u.base; 849 850 /* ??? */ 851 if (status & 0x40000000) 852 { 853 status = lp->tx_ring[cur_tx_slot_nr].misc; 854 ec->eth_stat.ets_sendErr++; 855 if (status & 0x0400) 856 ec->eth_stat.ets_transAb++; 857 if (status & 0x0800) 858 ec->eth_stat.ets_carrSense++; 859 if (status & 0x1000) 860 ec->eth_stat.ets_OWC++; 861 if (status & 0x4000) 862 { 863 ec->eth_stat.ets_fifoUnder++; 864 must_restart=1; 865 } 866 } 867 else 868 { 869 if (status & 0x18000000) 870 ec->eth_stat.ets_collision++; 871 ec->eth_stat.ets_packetT++; 872 } 873 } 874 /* transmit a packet on the next slot if it exists. */ 875 check = 0; 876 if (isstored[cur_tx_slot_nr]==1) 877 { 878 /* free the tx-slot just transmitted */ 879 isstored[cur_tx_slot_nr]=0; 880 cur_tx_slot_nr = (cur_tx_slot_nr + 1) & TX_RING_MOD_MASK; 881 882 /* next tx-slot is ready? */ 883 if (isstored[cur_tx_slot_nr]==1) 884 check=1; 885 else 886 check=0; 887 } 888 else 889 { 890 panic("got premature TX INT.."); 891 } 892 if (check==1) 893 { 894 lp->tx_ring[cur_tx_slot_nr].u.addr[3] = 0x83; 895 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_IENA|LANCE_CSR0_TDMD); 896 } 897 /* we set a buffered message in the slot if it exists. */ 898 /* and transmit it, if needed. */ 899 if (ec->flags & ECF_SEND_AVAIL) 900 ec_send(ec); 901 } 902 if (isr & LANCE_CSR0_RINT) 903 { 904 #if VERBOSE 905 printf("RX INT\n"); 906 #endif 907 ec_recv(ec); 908 } 909 910 if (isr & ISR_RST) 911 { 912 ec->flags = ECF_STOPPED; 913 #if VERBOSE 914 printf("ISR_RST\n"); 915 #endif 916 break; 917 } 918 919 /* ??? cf. lance driver on linux */ 920 if (must_restart == 1) 921 { 922 #if VERBOSE 923 printf("ETH: restarting...\n"); 924 #endif 925 /* stop */ 926 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STOP); 927 /* start */ 928 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STRT); 929 } 930 } 931 932 if ((ec->flags & (ECF_READING|ECF_STOPPED)) == (ECF_READING|ECF_STOPPED)) 933 { 934 #if VERBOSE 935 printf("ETH: resetting...\n"); 936 #endif 937 ec_reset(ec); 938 } 939 } 940 941 /*===========================================================================* 942 * ec_reset * 943 *===========================================================================*/ 944 static void ec_reset(ec) 945 ether_card_t *ec; 946 { 947 /* Stop/start the chip, and clear all RX,TX-slots */ 948 unsigned short ioaddr = ec->ec_port; 949 int i; 950 951 /* stop */ 952 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STOP); 953 /* start */ 954 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STRT); 955 956 /* purge Tx-ring */ 957 tx_slot_nr = cur_tx_slot_nr = 0; 958 for (i=0; i<TX_RING_SIZE; i++) 959 { 960 lp->tx_ring[i].u.base = 0; 961 isstored[i]=0; 962 } 963 964 /* re-init Rx-ring */ 965 rx_slot_nr = 0; 966 for (i=0; i<RX_RING_SIZE; i++) 967 { 968 lp->rx_ring[i].buf_length = -ETH_FRAME_LEN; 969 lp->rx_ring[i].u.addr[3] |= 0x80; 970 } 971 972 /* store a buffered message on the slot if exists */ 973 ec_send(ec); 974 ec->flags &= ~ECF_STOPPED; 975 } 976 977 /*===========================================================================* 978 * ec_send * 979 *===========================================================================*/ 980 static void ec_send(ec) 981 ether_card_t *ec; 982 { 983 /* from ec_check_ints() or ec_reset(). */ 984 /* this function proccesses the buffered message. (slot/transmit) */ 985 if (!(ec->flags & ECF_SEND_AVAIL)) 986 return; 987 988 ec->flags &= ~ECF_SEND_AVAIL; 989 switch(ec->sendmsg.m_type) 990 { 991 case DL_WRITEV_S: do_vwrite_s(&ec->sendmsg, TRUE); break; 992 default: 993 panic("wrong type: %d", ec->sendmsg.m_type); 994 break; 995 } 996 } 997 998 /*===========================================================================* 999 * do_vread_s * 1000 *===========================================================================*/ 1001 static void do_vread_s(const message *mp) 1002 { 1003 int count, r; 1004 ether_card_t *ec; 1005 1006 ec= &ec_state; 1007 1008 ec->client= mp->m_source; 1009 count = mp->m_net_netdrv_dl_readv_s.count; 1010 1011 r = sys_safecopyfrom(mp->m_source, mp->m_net_netdrv_dl_readv_s.grant, 0, 1012 (vir_bytes)ec->read_iovec.iod_iovec, 1013 (count > IOVEC_NR ? IOVEC_NR : count) * 1014 sizeof(iovec_s_t)); 1015 if (r != OK) 1016 panic("do_vread_s: sys_safecopyfrom failed: %d", r); 1017 ec->read_iovec.iod_iovec_s = count; 1018 ec->read_iovec.iod_proc_nr = mp->m_source; 1019 ec->read_iovec.iod_grant = mp->m_net_netdrv_dl_readv_s.grant; 1020 ec->read_iovec.iod_iovec_offset = 0; 1021 1022 ec->tmp_iovec = ec->read_iovec; 1023 1024 ec->flags |= ECF_READING; 1025 1026 ec_recv(ec); 1027 1028 if ((ec->flags & (ECF_READING|ECF_STOPPED)) == (ECF_READING|ECF_STOPPED)) 1029 ec_reset(ec); 1030 reply(ec); 1031 } 1032 1033 /*===========================================================================* 1034 * ec_recv * 1035 *===========================================================================*/ 1036 static void ec_recv(ec) 1037 ether_card_t *ec; 1038 { 1039 vir_bytes length; 1040 int packet_processed; 1041 int status; 1042 unsigned short ioaddr = ec->ec_port; 1043 1044 if ((ec->flags & ECF_READING)==0) 1045 return; 1046 if (!(ec->flags & ECF_ENABLED)) 1047 return; 1048 1049 /* we check all the received slots until find a properly received packet */ 1050 packet_processed = FALSE; 1051 while (!packet_processed) 1052 { 1053 status = lp->rx_ring[rx_slot_nr].u.base >> 24; 1054 if ( (status & 0x80) == 0x00 ) 1055 { 1056 status = lp->rx_ring[rx_slot_nr].u.base >> 24; 1057 1058 /* ??? */ 1059 if (status != 0x03) 1060 { 1061 if (status & 0x01) 1062 ec->eth_stat.ets_recvErr++; 1063 if (status & 0x04) 1064 ec->eth_stat.ets_fifoOver++; 1065 if (status & 0x08) 1066 ec->eth_stat.ets_CRCerr++; 1067 if (status & 0x10) 1068 ec->eth_stat.ets_OVW++; 1069 if (status & 0x20) 1070 ec->eth_stat.ets_frameAll++; 1071 length = 0; 1072 } 1073 else 1074 { 1075 ec->eth_stat.ets_packetR++; 1076 length = lp->rx_ring[rx_slot_nr].msg_length; 1077 } 1078 if (length > 0) 1079 { 1080 ec_nic2user(ec, (int)(lp->rbuf[rx_slot_nr]), 1081 &ec->read_iovec, 0, length); 1082 1083 ec->read_s = length; 1084 ec->flags |= ECF_PACK_RECV; 1085 ec->flags &= ~ECF_READING; 1086 packet_processed = TRUE; 1087 } 1088 /* set up this slot again, and we move to the next slot */ 1089 lp->rx_ring[rx_slot_nr].buf_length = -ETH_FRAME_LEN; 1090 lp->rx_ring[rx_slot_nr].u.addr[3] |= 0x80; 1091 1092 write_csr(ioaddr, LANCE_CSR0, 1093 LANCE_CSR0_BABL|LANCE_CSR0_CERR|LANCE_CSR0_MISS 1094 |LANCE_CSR0_MERR|LANCE_CSR0_IDON|LANCE_CSR0_IENA); 1095 1096 rx_slot_nr = (rx_slot_nr + 1) & RX_RING_MOD_MASK; 1097 } 1098 else 1099 break; 1100 } 1101 } 1102 1103 /*===========================================================================* 1104 * do_vwrite_s * 1105 *===========================================================================*/ 1106 static void do_vwrite_s(mp, from_int) 1107 message *mp; 1108 int from_int; 1109 { 1110 int count, check, r; 1111 ether_card_t *ec; 1112 unsigned short ioaddr; 1113 1114 ec = &ec_state; 1115 1116 ec->client= mp->m_source; 1117 count = mp->m_net_netdrv_dl_writev_s.count; 1118 1119 if (isstored[tx_slot_nr]==1) 1120 { 1121 /* all slots are used, so this message is buffered */ 1122 ec->sendmsg= *mp; 1123 ec->flags |= ECF_SEND_AVAIL; 1124 reply(ec); 1125 return; 1126 } 1127 1128 /* convert the message to write_iovec */ 1129 r = sys_safecopyfrom(mp->m_source, mp->m_net_netdrv_dl_writev_s.grant, 0, 1130 (vir_bytes)ec->write_iovec.iod_iovec, 1131 (count > IOVEC_NR ? IOVEC_NR : count) * 1132 sizeof(iovec_s_t)); 1133 if (r != OK) 1134 panic("do_vwrite_s: sys_safecopyfrom failed: %d", r); 1135 ec->write_iovec.iod_iovec_s = count; 1136 ec->write_iovec.iod_proc_nr = mp->m_source; 1137 ec->write_iovec.iod_grant = mp->m_net_netdrv_dl_writev_s.grant; 1138 ec->write_iovec.iod_iovec_offset = 0; 1139 1140 ec->tmp_iovec = ec->write_iovec; 1141 ec->write_s = calc_iovec_size(&ec->tmp_iovec); 1142 1143 /* copy write_iovec to the slot on DMA address */ 1144 ec_user2nic(ec, &ec->write_iovec, 0, 1145 (int)(lp->tbuf[tx_slot_nr]), ec->write_s); 1146 /* set-up for transmitting, and transmit it if needed. */ 1147 lp->tx_ring[tx_slot_nr].buf_length = -ec->write_s; 1148 lp->tx_ring[tx_slot_nr].misc = 0x0; 1149 lp->tx_ring[tx_slot_nr].u.base 1150 = virt_to_bus(lp->tbuf[tx_slot_nr]) & 0xffffff; 1151 isstored[tx_slot_nr]=1; 1152 if (cur_tx_slot_nr == tx_slot_nr) 1153 check=1; 1154 else 1155 check=0; 1156 tx_slot_nr = (tx_slot_nr + 1) & TX_RING_MOD_MASK; 1157 1158 if (check == 1) 1159 { 1160 ioaddr = ec->ec_port; 1161 lp->tx_ring[cur_tx_slot_nr].u.addr[3] = 0x83; 1162 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_IENA|LANCE_CSR0_TDMD); 1163 } 1164 1165 ec->flags |= ECF_PACK_SEND; 1166 1167 /* reply by calling do_int() if this function is called from interrupt. */ 1168 if (from_int) 1169 return; 1170 reply(ec); 1171 } 1172 1173 1174 /*===========================================================================* 1175 * ec_user2nic * 1176 *===========================================================================*/ 1177 static void ec_user2nic(ec, iovp, offset, nic_addr, count) 1178 ether_card_t *ec; 1179 iovec_dat_t *iovp; 1180 vir_bytes offset; 1181 int nic_addr; 1182 vir_bytes count; 1183 { 1184 int bytes, i, r; 1185 1186 i= 0; 1187 while (count > 0) 1188 { 1189 if (i >= IOVEC_NR) 1190 { 1191 ec_next_iovec(iovp); 1192 i= 0; 1193 continue; 1194 } 1195 if (offset >= iovp->iod_iovec[i].iov_size) 1196 { 1197 offset -= iovp->iod_iovec[i].iov_size; 1198 i++; 1199 continue; 1200 } 1201 bytes = iovp->iod_iovec[i].iov_size - offset; 1202 if (bytes > count) 1203 bytes = count; 1204 1205 if ( (r=sys_safecopyfrom(iovp->iod_proc_nr, 1206 iovp->iod_iovec[i].iov_grant, offset, 1207 nic_addr, bytes )) != OK ) 1208 panic("ec_user2nic: sys_safecopyfrom failed: %d", r); 1209 1210 count -= bytes; 1211 nic_addr += bytes; 1212 offset += bytes; 1213 } 1214 } 1215 1216 /*===========================================================================* 1217 * ec_nic2user * 1218 *===========================================================================*/ 1219 static void ec_nic2user(ec, nic_addr, iovp, offset, count) 1220 ether_card_t *ec; 1221 int nic_addr; 1222 iovec_dat_t *iovp; 1223 vir_bytes offset; 1224 vir_bytes count; 1225 { 1226 int bytes, i, r; 1227 1228 i= 0; 1229 while (count > 0) 1230 { 1231 if (i >= IOVEC_NR) 1232 { 1233 ec_next_iovec(iovp); 1234 i= 0; 1235 continue; 1236 } 1237 if (offset >= iovp->iod_iovec[i].iov_size) 1238 { 1239 offset -= iovp->iod_iovec[i].iov_size; 1240 i++; 1241 continue; 1242 } 1243 bytes = iovp->iod_iovec[i].iov_size - offset; 1244 if (bytes > count) 1245 bytes = count; 1246 if ( (r=sys_safecopyto( iovp->iod_proc_nr, iovp->iod_iovec[i].iov_grant, 1247 offset, nic_addr, bytes )) != OK ) 1248 panic("ec_nic2user: sys_safecopyto failed: %d", r); 1249 1250 count -= bytes; 1251 nic_addr += bytes; 1252 offset += bytes; 1253 } 1254 } 1255 1256 1257 /*===========================================================================* 1258 * calc_iovec_size * 1259 *===========================================================================*/ 1260 static int calc_iovec_size(iovec_dat_t *iovp) 1261 { 1262 int size,i; 1263 1264 size = i = 0; 1265 1266 while (i < iovp->iod_iovec_s) 1267 { 1268 if (i >= IOVEC_NR) 1269 { 1270 ec_next_iovec(iovp); 1271 i= 0; 1272 continue; 1273 } 1274 size += iovp->iod_iovec[i].iov_size; 1275 i++; 1276 } 1277 1278 return size; 1279 } 1280 1281 /*===========================================================================* 1282 * ec_next_iovec * 1283 *===========================================================================*/ 1284 static void ec_next_iovec(iovp) 1285 iovec_dat_t *iovp; 1286 { 1287 int r; 1288 1289 iovp->iod_iovec_s -= IOVEC_NR; 1290 iovp->iod_iovec_offset += IOVEC_NR * sizeof(iovec_s_t); 1291 1292 r = sys_safecopyfrom(iovp->iod_proc_nr, iovp->iod_grant, 1293 iovp->iod_iovec_offset, 1294 (vir_bytes)iovp->iod_iovec, 1295 (iovp->iod_iovec_s > IOVEC_NR ? 1296 IOVEC_NR : iovp->iod_iovec_s) * 1297 sizeof(iovec_s_t)); 1298 if (r != OK) 1299 panic("ec_next_iovec: sys_safecopyfrom failed: %d", r); 1300 } 1301 1302 1303 /*===========================================================================* 1304 * do_getstat_s * 1305 *===========================================================================*/ 1306 static void do_getstat_s(mp) 1307 message *mp; 1308 { 1309 int r; 1310 ether_card_t *ec; 1311 1312 ec= &ec_state; 1313 1314 r = sys_safecopyto(mp->m_source, mp->m_net_netdrv_dl_getstat_s.grant, 0, 1315 (vir_bytes)&ec->eth_stat, sizeof(ec->eth_stat)); 1316 1317 if (r != OK) 1318 panic("do_getstat_s: sys_safecopyto failed: %d", r); 1319 1320 mp->m_type= DL_STAT_REPLY; 1321 r= ipc_send(mp->m_source, mp); 1322 if (r != OK) 1323 panic("do_getstat_s: send failed: %d", r); 1324 } 1325 1326 /*===========================================================================* 1327 * lance_stop * 1328 *===========================================================================*/ 1329 static void lance_stop(ec) 1330 ether_card_t *ec; 1331 { 1332 unsigned short ioaddr; 1333 1334 if (!(ec->flags & ECF_ENABLED)) 1335 return; 1336 1337 ioaddr = ec->ec_port; 1338 1339 /* stop */ 1340 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STOP); 1341 1342 /* Reset */ 1343 in_word(ioaddr+LANCE_RESET); 1344 1345 ec->flags = ECF_EMPTY; 1346 } 1347 1348 /*===========================================================================* 1349 * getAddressing * 1350 *===========================================================================*/ 1351 static void getAddressing(devind, ec) 1352 int devind; 1353 ether_card_t *ec; 1354 { 1355 unsigned int membase, ioaddr; 1356 int reg, irq; 1357 1358 for (reg = PCI_BAR; reg <= PCI_BAR_6; reg += 4) 1359 { 1360 ioaddr = pci_attr_r32(devind, reg); 1361 1362 if ((ioaddr & PCI_BAR_IO_MASK) == 0 || (ioaddr & PCI_BAR_IO) == 0) 1363 continue; 1364 /* Strip the I/O address out of the returned value */ 1365 ioaddr &= PCI_BAR_IO_MASK; 1366 /* Get the memory base address */ 1367 membase = pci_attr_r32(devind, PCI_BAR_2); 1368 /* KK: Get the IRQ number */ 1369 irq = pci_attr_r8(devind, PCI_IPR); 1370 if (irq) 1371 irq = pci_attr_r8(devind, PCI_ILR); 1372 1373 ec->ec_linmem = membase; 1374 ec->ec_port = ioaddr; 1375 ec->ec_irq = irq; 1376 } 1377 } 1378 1379 /*===========================================================================* 1380 * lance_probe * 1381 *===========================================================================*/ 1382 static int lance_probe(ec, skip) 1383 ether_card_t *ec; 1384 int skip; 1385 { 1386 unsigned short pci_cmd; 1387 unsigned short ioaddr; 1388 int lance_version, chip_version; 1389 int devind, r; 1390 u16_t vid, did; 1391 1392 r= pci_first_dev(&devind, &vid, &did); 1393 if (r == 0) 1394 return 0; 1395 1396 while (skip--) 1397 { 1398 r= pci_next_dev(&devind, &vid, &did); 1399 if (!r) 1400 return 0; 1401 } 1402 1403 pci_reserve(devind); 1404 1405 getAddressing(devind, ec); 1406 1407 1408 /* ===== Bus Master ? ===== */ 1409 pci_cmd = pci_attr_r32(devind, PCI_CR); 1410 if (!(pci_cmd & PCI_CR_MAST_EN)) { 1411 pci_cmd |= PCI_CR_MAST_EN; 1412 pci_attr_w32(devind, PCI_CR, pci_cmd); 1413 } 1414 1415 /* ===== Probe Details ===== */ 1416 ioaddr = ec->ec_port; 1417 1418 /* Reset */ 1419 in_word(ioaddr+LANCE_RESET); 1420 1421 if (read_csr(ioaddr, LANCE_CSR0) != LANCE_CSR0_STOP) 1422 { 1423 ec->mode=EC_DISABLED; 1424 } 1425 1426 /* Probe Chip Version */ 1427 out_word(ioaddr+LANCE_ADDR, 88); /* Get the version of the chip */ 1428 if (in_word(ioaddr+LANCE_ADDR) != 88) 1429 lance_version = 0; 1430 else 1431 { 1432 chip_version = read_csr(ioaddr, LANCE_CSR88); 1433 chip_version |= read_csr(ioaddr, LANCE_CSR89) << 16; 1434 1435 if ((chip_version & 0xfff) != 0x3) 1436 { 1437 ec->mode=EC_DISABLED; 1438 } 1439 chip_version = (chip_version >> 12) & 0xffff; 1440 for (lance_version = 1; chip_table[lance_version].id_number != 0; 1441 ++lance_version) 1442 if (chip_table[lance_version].id_number == chip_version) 1443 break; 1444 } 1445 1446 #if VERBOSE 1447 printf("%s: %s at %X:%d\n", 1448 ec->port_name, chip_table[lance_version].name, 1449 ec->ec_port, ec->ec_irq); 1450 #endif 1451 1452 return lance_version; 1453 } 1454 1455 /*===========================================================================* 1456 * lance_init_card * 1457 *===========================================================================*/ 1458 static void lance_init_card(ec) 1459 ether_card_t *ec; 1460 { 1461 int i; 1462 Address l = (vir_bytes)lance_buf; 1463 unsigned short ioaddr = ec->ec_port; 1464 1465 /* ============= setup init_block(cf. lance_probe1) ================ */ 1466 /* make sure data structure is 8-byte aligned and below 16MB (for DMA) */ 1467 1468 lp = (struct lance_interface *)l; 1469 1470 /* disable Tx and Rx */ 1471 lp->init_block.mode = LANCE_CSR15_DTX|LANCE_CSR15_DRX; 1472 lp->init_block.filter[0] = lp->init_block.filter[1] = 0x0; 1473 /* using multiple Rx/Tx buffer */ 1474 lp->init_block.rx_ring 1475 = (virt_to_bus(&lp->rx_ring) & 0xffffff) | RX_RING_LEN_BITS; 1476 lp->init_block.tx_ring 1477 = (virt_to_bus(&lp->tx_ring) & 0xffffff) | TX_RING_LEN_BITS; 1478 1479 l = virt_to_bus(&lp->init_block); 1480 write_csr(ioaddr, LANCE_CSR1, (unsigned short)l); 1481 write_csr(ioaddr, LANCE_CSR2, (unsigned short)(l >> 16)); 1482 write_csr(ioaddr, LANCE_CSR4, 1483 LANCE_CSR4_APAD_XMT|LANCE_CSR4_MFCOM|LANCE_CSR4_RCVCCOM 1484 |LANCE_CSR4_TXSTRTM|LANCE_CSR4_JABM); 1485 1486 /* ============= Get MAC address (cf. lance_probe1) ================ */ 1487 for (i = 0; i < 6; ++i) 1488 ec->mac_address.ea_addr[i]=in_byte(ioaddr+LANCE_ETH_ADDR+i); 1489 1490 /* ============ (re)start init_block(cf. lance_reset) =============== */ 1491 /* Reset the LANCE */ 1492 (void)in_word(ioaddr+LANCE_RESET); 1493 1494 /* ----- Re-initialize the LANCE ----- */ 1495 /* Set station address */ 1496 for (i = 0; i < 6; ++i) 1497 lp->init_block.phys_addr[i] = ec->mac_address.ea_addr[i]; 1498 /* Preset the receive ring headers */ 1499 for (i=0; i<RX_RING_SIZE; i++) 1500 { 1501 lp->rx_ring[i].buf_length = -ETH_FRAME_LEN; 1502 /* OWN */ 1503 lp->rx_ring[i].u.base = virt_to_bus(lp->rbuf[i]) & 0xffffff; 1504 /* we set the top byte as the very last thing */ 1505 lp->rx_ring[i].u.addr[3] = 0x80; 1506 } 1507 /* Preset the transmitting ring headers */ 1508 for (i=0; i<TX_RING_SIZE; i++) 1509 { 1510 lp->tx_ring[i].u.base = 0; 1511 isstored[i] = 0; 1512 } 1513 /* enable Rx and Tx */ 1514 lp->init_block.mode = 0x0; 1515 1516 l = (Address)virt_to_bus(&lp->init_block); 1517 write_csr(ioaddr, LANCE_CSR1, (short)l); 1518 write_csr(ioaddr, LANCE_CSR2, (short)(l >> 16)); 1519 write_csr(ioaddr, LANCE_CSR4, 1520 LANCE_CSR4_APAD_XMT|LANCE_CSR4_MFCOM|LANCE_CSR4_RCVCCOM 1521 |LANCE_CSR4_TXSTRTM|LANCE_CSR4_JABM); 1522 1523 /* ----- start when init done. ----- */ 1524 /* stop */ 1525 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STOP); 1526 /* init */ 1527 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_INIT); 1528 /* poll for IDON */ 1529 for (i = 10000; i > 0; --i) 1530 if (read_csr(ioaddr, LANCE_CSR0) & LANCE_CSR0_IDON) 1531 break; 1532 1533 /* Set 'Multicast Table' */ 1534 for (i=0;i<4;++i) 1535 { 1536 write_csr(ioaddr, LANCE_CSR8 + i, 0xffff); 1537 } 1538 1539 /* Set 'Receive Mode' */ 1540 if (ec->flags & ECF_PROMISC) 1541 { 1542 write_csr(ioaddr, LANCE_CSR15, LANCE_CSR15_PROM); 1543 } 1544 else 1545 { 1546 if (ec->flags & (ECF_BROAD | ECF_MULTI)) 1547 { 1548 write_csr(ioaddr, LANCE_CSR15, 0x0000); 1549 } 1550 else 1551 { 1552 write_csr(ioaddr, LANCE_CSR15, LANCE_CSR15_DRCVBC); 1553 } 1554 } 1555 1556 /* start && enable interrupt */ 1557 write_csr(ioaddr, LANCE_CSR0, 1558 LANCE_CSR0_IDON|LANCE_CSR0_IENA|LANCE_CSR0_STRT); 1559 1560 return; 1561 } 1562 1563 /*===========================================================================* 1564 * in_byte * 1565 *===========================================================================*/ 1566 static u8_t in_byte(port_t port) 1567 { 1568 int r; 1569 u32_t value; 1570 1571 r= sys_inb(port, &value); 1572 if (r != OK) 1573 panic("sys_inb failed: %d", r); 1574 return value; 1575 } 1576 1577 /*===========================================================================* 1578 * in_word * 1579 *===========================================================================*/ 1580 static u16_t in_word(port_t port) 1581 { 1582 int r; 1583 u32_t value; 1584 1585 r= sys_inw(port, &value); 1586 if (r != OK) 1587 panic("sys_inw failed: %d", r); 1588 return value; 1589 } 1590 1591 1592 /*===========================================================================* 1593 * out_word * 1594 *===========================================================================*/ 1595 static void out_word(port_t port, u16_t value) 1596 { 1597 int r; 1598 1599 r= sys_outw(port, value); 1600 if (r != OK) 1601 panic("sys_outw failed: %d", r); 1602 } 1603 1604 /*===========================================================================* 1605 * read_csr * 1606 *===========================================================================*/ 1607 static u16_t read_csr(port_t ioaddr, u16_t csrno) 1608 { 1609 out_word(ioaddr+LANCE_ADDR, csrno); 1610 return in_word(ioaddr+LANCE_DATA); 1611 } 1612 1613 /*===========================================================================* 1614 * write_csr * 1615 *===========================================================================*/ 1616 static void write_csr(port_t ioaddr, u16_t csrno, u16_t value) 1617 { 1618 out_word(ioaddr+LANCE_ADDR, csrno); 1619 out_word(ioaddr+LANCE_DATA, value); 1620 } 1621