1 /* 2 * dp8390.c 3 * 4 * This file contains a ethernet device driver for NS dp8390 based ethernet 5 * cards. 6 * 7 * Created: before Dec 28, 1992 by Philip Homburg <philip@f-mnx.phicoh.com> 8 * 9 * Modified Mar 10 1994 by Philip Homburg 10 * Become a generic dp8390 driver. 11 * 12 * Modified Dec 20 1996 by G. Falzoni <falzoni@marina.scn.de> 13 * Added support for 3c503 boards. 14 */ 15 16 #include <minix/drivers.h> 17 #include <minix/netdriver.h> 18 19 #include <sys/mman.h> 20 #include "assert.h" 21 22 #include "local.h" 23 #include "dp8390.h" 24 25 static dpeth_t de_state; 26 27 u32_t system_hz; 28 29 /* Configuration */ 30 typedef struct dp_conf 31 { 32 port_t dpc_port; 33 int dpc_irq; 34 phys_bytes dpc_mem; 35 } dp_conf_t; 36 37 #define DP_CONF_NR 4 38 static dp_conf_t dp_conf[DP_CONF_NR]= /* Card addresses */ 39 { 40 /* I/O port, IRQ, Buffer address. */ 41 { 0x280, 3, 0xD0000, }, 42 { 0x300, 5, 0xC8000, }, 43 { 0x380, 10, 0xD8000, }, 44 { 0x000, 0, 0x00000, }, 45 }; 46 47 /* Card inits configured out? */ 48 #if !ENABLE_WDETH 49 #define wdeth_probe(dep) (0) 50 #endif 51 #if !ENABLE_NE2000 52 #define ne_probe(dep) (0) 53 #endif 54 #if !ENABLE_3C503 55 #define el2_probe(dep) (0) 56 #endif 57 58 /* Some clones of the dp8390 and the PC emulator 'Bochs' require the CR_STA 59 * on writes to the CR register. Additional CR_STAs do not appear to hurt 60 * genuine dp8390s 61 */ 62 #define CR_EXTRA CR_STA 63 64 static int do_init(unsigned int instance, netdriver_addr_t *addr, 65 uint32_t *caps, unsigned int *ticks); 66 static void pci_conf(unsigned int instance); 67 static int do_send(struct netdriver_data *data, size_t size); 68 static ssize_t do_recv(struct netdriver_data *data, size_t max); 69 static void do_set_mode(unsigned int mode, const netdriver_addr_t *mcast_list, 70 unsigned int mcast_count); 71 static void do_stop(void); 72 static void dp_init(dpeth_t *dep, unsigned int instance); 73 static void dp_confaddr(dpeth_t *dep, unsigned int instance); 74 static void dp_reset(dpeth_t *dep); 75 static void do_intr(unsigned int mask); 76 static void do_tick(void); 77 static void dp_getblock(dpeth_t *dep, int page, size_t offset, size_t 78 size, void *dst); 79 static void dp_pio8_getblock(dpeth_t *dep, int page, size_t offset, 80 size_t size, void *dst); 81 static void dp_pio16_getblock(dpeth_t *dep, int page, size_t offset, 82 size_t size, void *dst); 83 static void dp_pkt2user_s(dpeth_t *dep, struct netdriver_data *data, int page, 84 size_t length); 85 static void dp_user2nic_s(dpeth_t *dep, struct netdriver_data *data, 86 int nic_addr, size_t offset, size_t count); 87 static void dp_pio8_user2nic_s(dpeth_t *dep, struct netdriver_data *data, 88 int nic_addr, size_t offset, size_t count); 89 static void dp_pio16_user2nic_s(dpeth_t *dep, struct netdriver_data *data, 90 int nic_addr, size_t offset, size_t count); 91 static void dp_nic2user_s(dpeth_t *dep, struct netdriver_data *data, 92 int nic_addr, size_t offset, size_t count); 93 static void dp_pio8_nic2user_s(dpeth_t *dep, struct netdriver_data *data, 94 int nic_addr, size_t offset, size_t count); 95 static void dp_pio16_nic2user_s(dpeth_t *dep, struct netdriver_data *data, 96 int nic_addr, size_t offset, size_t count); 97 static void conf_hw(dpeth_t *dep, unsigned int instance); 98 static void update_conf(dpeth_t *dep, dp_conf_t *dcp, unsigned int instance); 99 static void map_hw_buffer(dpeth_t *dep); 100 static void insb(port_t port, void *buf, size_t size); 101 static void insw(port_t port, void *buf, size_t size); 102 103 static const struct netdriver dp_table = { 104 .ndr_name = "dp", 105 .ndr_init = do_init, 106 .ndr_stop = do_stop, 107 .ndr_set_mode = do_set_mode, 108 .ndr_recv = do_recv, 109 .ndr_send = do_send, 110 .ndr_intr = do_intr, 111 .ndr_tick = do_tick 112 }; 113 114 /*===========================================================================* 115 * main * 116 *===========================================================================*/ 117 int main(int argc, char *argv[]) 118 { 119 env_setargs(argc, argv); 120 121 netdriver_task(&dp_table); 122 123 return 0; 124 } 125 126 /*===========================================================================* 127 * do_init * 128 *===========================================================================*/ 129 static int do_init(unsigned int instance, netdriver_addr_t *addr, 130 uint32_t *caps, unsigned int *ticks) 131 { 132 /* Initialize the dp8390 driver. */ 133 dpeth_t *dep; 134 135 system_hz = sys_hz(); 136 137 dep = &de_state; 138 memset(dep, 0, sizeof(*dep)); 139 140 pci_conf(instance); /* Configure PCI devices. */ 141 142 /* This is the default, try to (re)locate the device. */ 143 conf_hw(dep, instance); 144 145 dp_init(dep, instance); 146 147 memcpy(addr, dep->de_address.na_addr, sizeof(*addr)); 148 *caps = NDEV_CAP_MCAST | NDEV_CAP_BCAST; 149 *ticks = sys_hz(); /* update statistics once a second */ 150 return OK; 151 } 152 153 #if 0 154 /*===========================================================================* 155 * dp8390_dump * 156 *===========================================================================*/ 157 void dp8390_dump(void) 158 { 159 dpeth_t *dep; 160 int isr; 161 162 dep = &de_state; 163 164 printf("\n"); 165 printf("dp8390 statistics of %s:\n", netdriver_name()); 166 167 isr= inb_reg0(dep, DP_ISR); 168 printf("dp_isr = 0x%x + 0x%x, de_flags = 0x%x\n", isr, 169 inb_reg0(dep, DP_ISR), dep->de_flags); 170 } 171 #endif 172 173 /*===========================================================================* 174 * pci_env * 175 *===========================================================================*/ 176 static int pci_env(unsigned int instance) 177 { 178 char envvar[16], value[EP_BUF_SIZE]; 179 const char punct[] = ":,;."; 180 181 strlcpy(envvar, "DPETH0", sizeof(envvar)); 182 envvar[5] += instance; 183 184 /* If no setting with this name is present, default to PCI. */ 185 if (env_get_param(envvar, value, sizeof(value)) != 0) 186 return TRUE; 187 188 /* Legacy support: check for a "pci" prefix. */ 189 return (strncmp(value, "pci", 3) == 0 && 190 strchr(punct, value[3]) != NULL); 191 } 192 193 /*===========================================================================* 194 * pci_conf * 195 *===========================================================================*/ 196 static void pci_conf(unsigned int instance) 197 { 198 struct dpeth *dep; 199 unsigned int i, pci_instance; 200 201 dep= &de_state; 202 203 if (!(dep->de_pci= pci_env(instance))) 204 return; /* no PCI config */ 205 206 /* Count the number of dp instances before this one that are configured 207 * for PCI, so that we can skip that many when enumerating PCI devices. 208 */ 209 pci_instance= 0; 210 for (i= 0; i < instance; i++) { 211 if (pci_env(i)) 212 pci_instance++; 213 } 214 215 if (!rtl_probe(dep, pci_instance)) 216 panic("no matching PCI device found"); 217 } 218 219 /*===========================================================================* 220 * do_send * 221 *===========================================================================*/ 222 static int do_send(struct netdriver_data *data, size_t size) 223 { 224 int sendq_head; 225 dpeth_t *dep; 226 227 dep= &de_state; 228 229 sendq_head= dep->de_sendq_head; 230 if (dep->de_sendq[sendq_head].sq_filled) 231 return SUSPEND; 232 233 (dep->de_user2nicf_s)(dep, data, 234 dep->de_sendq[sendq_head].sq_sendpage * DP_PAGESIZE, 0, size); 235 236 dep->de_sendq[sendq_head].sq_filled= TRUE; 237 if (dep->de_sendq_tail == sendq_head) 238 { 239 outb_reg0(dep, DP_TPSR, dep->de_sendq[sendq_head].sq_sendpage); 240 outb_reg0(dep, DP_TBCR1, size >> 8); 241 outb_reg0(dep, DP_TBCR0, size & 0xff); 242 outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);/* there it goes.. */ 243 } 244 else 245 dep->de_sendq[sendq_head].sq_size= size; 246 247 if (++sendq_head == dep->de_sendq_nr) 248 sendq_head= 0; 249 assert(sendq_head < SENDQ_NR); 250 dep->de_sendq_head= sendq_head; 251 252 return OK; 253 } 254 255 /*===========================================================================* 256 * do_set_mode * 257 *===========================================================================*/ 258 static void do_set_mode(unsigned int mode, 259 const netdriver_addr_t * mcast_list __unused, 260 unsigned int mcast_count __unused) 261 { 262 dpeth_t *dep; 263 int dp_rcr_reg; 264 265 dep = &de_state; 266 267 outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA); 268 269 dp_rcr_reg = 0; 270 if (mode & NDEV_MODE_PROMISC) 271 dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM; 272 if (mode & NDEV_MODE_BCAST) 273 dp_rcr_reg |= RCR_AB; 274 if (mode & (NDEV_MODE_MCAST_LIST | NDEV_MODE_MCAST_ALL)) 275 dp_rcr_reg |= RCR_AM; 276 outb_reg0(dep, DP_RCR, dp_rcr_reg); 277 } 278 279 /*===========================================================================* 280 * dp_update_stats * 281 *===========================================================================*/ 282 static void dp_update_stats(dpeth_t * dep) 283 { 284 285 netdriver_stat_ierror(inb_reg0(dep, DP_CNTR0)); 286 netdriver_stat_ierror(inb_reg0(dep, DP_CNTR1)); 287 netdriver_stat_ierror(inb_reg0(dep, DP_CNTR2)); 288 } 289 290 /*===========================================================================* 291 * do_tick * 292 *===========================================================================*/ 293 static void do_tick(void) 294 { 295 296 dp_update_stats(&de_state); 297 } 298 299 /*===========================================================================* 300 * do_stop * 301 *===========================================================================*/ 302 static void do_stop(void) 303 { 304 dpeth_t *dep; 305 306 dep = &de_state; 307 308 outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT); 309 (dep->de_stopf)(dep); 310 } 311 312 /*===========================================================================* 313 * dp_init * 314 *===========================================================================*/ 315 static void dp_init(dpeth_t *dep, unsigned int instance) 316 { 317 int i, r; 318 319 /* General initialization */ 320 dep->de_flags = DEF_EMPTY; 321 (*dep->de_initf)(dep); 322 323 dp_confaddr(dep, instance); 324 325 if (debug) 326 { 327 printf("%s: Ethernet address ", netdriver_name()); 328 for (i= 0; i < 6; i++) 329 printf("%x%c", dep->de_address.na_addr[i], 330 i < 5 ? ':' : '\n'); 331 } 332 333 /* Map buffer */ 334 map_hw_buffer(dep); 335 336 /* Initialization of the dp8390 following the mandatory procedure 337 * in reference manual ("DP8390D/NS32490D NIC Network Interface 338 * Controller", National Semiconductor, July 1995, Page 29). 339 */ 340 /* Step 1: */ 341 outb_reg0(dep, DP_CR, CR_PS_P0 | CR_STP | CR_DM_ABORT); 342 /* Step 2: */ 343 if (dep->de_16bit) 344 outb_reg0(dep, DP_DCR, DCR_WORDWIDE | DCR_8BYTES | DCR_BMS); 345 else 346 outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES | DCR_BMS); 347 /* Step 3: */ 348 outb_reg0(dep, DP_RBCR0, 0); 349 outb_reg0(dep, DP_RBCR1, 0); 350 /* Step 4: */ 351 outb_reg0(dep, DP_RCR, 0); 352 /* Step 5: */ 353 outb_reg0(dep, DP_TCR, TCR_INTERNAL); 354 /* Step 6: */ 355 outb_reg0(dep, DP_BNRY, dep->de_startpage); 356 outb_reg0(dep, DP_PSTART, dep->de_startpage); 357 outb_reg0(dep, DP_PSTOP, dep->de_stoppage); 358 /* Step 7: */ 359 outb_reg0(dep, DP_ISR, 0xFF); 360 /* Step 8: */ 361 outb_reg0(dep, DP_IMR, IMR_PRXE | IMR_PTXE | IMR_RXEE | IMR_TXEE | 362 IMR_OVWE | IMR_CNTE); 363 /* Step 9: */ 364 outb_reg0(dep, DP_CR, CR_PS_P1 | CR_DM_ABORT | CR_STP); 365 366 outb_reg1(dep, DP_PAR0, dep->de_address.na_addr[0]); 367 outb_reg1(dep, DP_PAR1, dep->de_address.na_addr[1]); 368 outb_reg1(dep, DP_PAR2, dep->de_address.na_addr[2]); 369 outb_reg1(dep, DP_PAR3, dep->de_address.na_addr[3]); 370 outb_reg1(dep, DP_PAR4, dep->de_address.na_addr[4]); 371 outb_reg1(dep, DP_PAR5, dep->de_address.na_addr[5]); 372 373 outb_reg1(dep, DP_MAR0, 0xff); 374 outb_reg1(dep, DP_MAR1, 0xff); 375 outb_reg1(dep, DP_MAR2, 0xff); 376 outb_reg1(dep, DP_MAR3, 0xff); 377 outb_reg1(dep, DP_MAR4, 0xff); 378 outb_reg1(dep, DP_MAR5, 0xff); 379 outb_reg1(dep, DP_MAR6, 0xff); 380 outb_reg1(dep, DP_MAR7, 0xff); 381 382 outb_reg1(dep, DP_CURR, dep->de_startpage + 1); 383 /* Step 10: */ 384 outb_reg0(dep, DP_CR, CR_DM_ABORT | CR_STA); 385 /* Step 11: */ 386 outb_reg0(dep, DP_TCR, TCR_NORMAL); 387 388 inb_reg0(dep, DP_CNTR0); /* reset counters by reading */ 389 inb_reg0(dep, DP_CNTR1); 390 inb_reg0(dep, DP_CNTR2); 391 392 /* Finish the initialization. */ 393 for (i= 0; i<dep->de_sendq_nr; i++) 394 dep->de_sendq[i].sq_filled= 0; 395 dep->de_sendq_head= 0; 396 dep->de_sendq_tail= 0; 397 if (!dep->de_prog_IO) 398 { 399 dep->de_user2nicf_s= dp_user2nic_s; 400 dep->de_nic2userf_s= dp_nic2user_s; 401 dep->de_getblockf= dp_getblock; 402 } 403 else if (dep->de_16bit) 404 { 405 dep->de_user2nicf_s= dp_pio16_user2nic_s; 406 dep->de_nic2userf_s= dp_pio16_nic2user_s; 407 dep->de_getblockf= dp_pio16_getblock; 408 } 409 else 410 { 411 dep->de_user2nicf_s= dp_pio8_user2nic_s; 412 dep->de_nic2userf_s= dp_pio8_nic2user_s; 413 dep->de_getblockf= dp_pio8_getblock; 414 } 415 416 /* Set the interrupt handler and policy. Do not automatically 417 * reenable interrupts. Return the IRQ line number on interrupts. 418 */ 419 dep->de_hook = dep->de_irq; 420 r= sys_irqsetpolicy(dep->de_irq, 0, &dep->de_hook); 421 if (r != OK) 422 panic("sys_irqsetpolicy failed: %d", r); 423 424 r= sys_irqenable(&dep->de_hook); 425 if (r != OK) 426 panic("unable to enable interrupts: %d", r); 427 } 428 429 /*===========================================================================* 430 * dp_confaddr * 431 *===========================================================================*/ 432 static void dp_confaddr(dpeth_t *dep, unsigned int instance) 433 { 434 int i; 435 char eakey[16]; 436 static char eafmt[]= "x:x:x:x:x:x"; 437 long v; 438 439 /* User defined ethernet address? */ 440 strlcpy(eakey, "DPETH0_EA", sizeof(eakey)); 441 eakey[5] += instance; 442 443 for (i= 0; i < 6; i++) 444 { 445 v= dep->de_address.na_addr[i]; 446 if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET) 447 { 448 break; 449 } 450 dep->de_address.na_addr[i]= v; 451 } 452 453 if (i != 0 && i != 6) env_panic(eakey); /* It's all or nothing */ 454 } 455 456 /*===========================================================================* 457 * dp_reset * 458 *===========================================================================*/ 459 static void dp_reset(dpeth_t *dep) 460 { 461 int i; 462 463 /* Stop chip */ 464 outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT); 465 outb_reg0(dep, DP_RBCR0, 0); 466 outb_reg0(dep, DP_RBCR1, 0); 467 for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RST) == 0); i++) 468 ; /* Do nothing */ 469 outb_reg0(dep, DP_TCR, TCR_1EXTERNAL|TCR_OFST); 470 outb_reg0(dep, DP_CR, CR_STA|CR_DM_ABORT); 471 outb_reg0(dep, DP_TCR, TCR_NORMAL); 472 473 /* Acknowledge the ISR_RDC (remote dma) interrupt. */ 474 for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RDC) == 0); i++) 475 ; /* Do nothing */ 476 outb_reg0(dep, DP_ISR, inb_reg0(dep, DP_ISR) & ~ISR_RDC); 477 478 /* Reset the transmit ring. If we were transmitting a packet, we 479 * pretend that the packet is processed. Higher layers will 480 * retransmit if the packet wasn't actually sent. 481 */ 482 dep->de_sendq_head= dep->de_sendq_tail= 0; 483 for (i= 0; i<dep->de_sendq_nr; i++) 484 dep->de_sendq[i].sq_filled= 0; 485 netdriver_send(); 486 dep->de_flags &= ~DEF_STOPPED; 487 } 488 489 /*===========================================================================* 490 * do_intr * 491 *===========================================================================*/ 492 static void do_intr(unsigned int __unused mask) 493 { 494 dpeth_t *dep; 495 int isr, tsr; 496 int r, size, sendq_tail; 497 498 dep = &de_state; 499 500 for(;;) 501 { 502 isr = inb_reg0(dep, DP_ISR); 503 if (!isr) 504 break; 505 outb_reg0(dep, DP_ISR, isr); 506 if (isr & (ISR_PTX|ISR_TXE)) 507 { 508 if (isr & ISR_TXE) 509 { 510 #if DEBUG 511 printf("%s: got send error\n", 512 netdriver_name()); 513 #endif 514 netdriver_stat_oerror(1); 515 } 516 else 517 { 518 tsr = inb_reg0(dep, DP_TSR); 519 520 if (tsr & TSR_PTX) { 521 /* Transmission was successful. */ 522 } 523 #if 0 /* Reserved in later manuals, should be ignored */ 524 if (!(tsr & TSR_DFR)) 525 { 526 /* In most (all?) implementations of 527 * the dp8390, this bit is set 528 * when the packet is not deferred 529 */ 530 } 531 #endif 532 if (tsr & TSR_COL) netdriver_stat_coll(1); 533 } 534 sendq_tail= dep->de_sendq_tail; 535 536 if (!(dep->de_sendq[sendq_tail].sq_filled)) 537 { 538 /* Software bug? */ 539 assert(!debug); 540 541 /* Or hardware bug? */ 542 printf( 543 "%s: transmit interrupt, but not sending\n", 544 netdriver_name()); 545 continue; 546 } 547 dep->de_sendq[sendq_tail].sq_filled= 0; 548 if (++sendq_tail == dep->de_sendq_nr) 549 sendq_tail= 0; 550 dep->de_sendq_tail= sendq_tail; 551 if (dep->de_sendq[sendq_tail].sq_filled) 552 { 553 size= dep->de_sendq[sendq_tail].sq_size; 554 outb_reg0(dep, DP_TPSR, 555 dep->de_sendq[sendq_tail].sq_sendpage); 556 outb_reg0(dep, DP_TBCR1, size >> 8); 557 outb_reg0(dep, DP_TBCR0, size & 0xff); 558 outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA); 559 } 560 netdriver_send(); 561 } 562 563 if (isr & ISR_PRX) 564 netdriver_recv(); 565 566 if (isr & ISR_RXE) 567 netdriver_stat_ierror(1); 568 if (isr & ISR_CNT) 569 dp_update_stats(dep); 570 if (isr & ISR_RDC) 571 { 572 /* Nothing to do */ 573 } 574 if (isr & ISR_RST) 575 { 576 /* this means we got an interrupt but the ethernet 577 * chip is shutdown. We set the flag DEF_STOPPED, 578 * and continue processing arrived packets. When the 579 * receive buffer is empty, we reset the dp8390. 580 */ 581 #if 0 582 { printW(); printf( 583 "%s: NIC stopped\n", netdriver_name()); } 584 #endif 585 dep->de_flags |= DEF_STOPPED; 586 netdriver_recv(); /* see if we can reset right now */ 587 break; 588 } 589 } 590 591 if ((r = sys_irqenable(&dep->de_hook)) != OK) 592 panic("unable enable interrupts: %d", r); 593 } 594 595 /*===========================================================================* 596 * do_recv * 597 *===========================================================================*/ 598 static ssize_t do_recv(struct netdriver_data *data, size_t max) 599 { 600 dpeth_t *dep; 601 dp_rcvhdr_t header; 602 unsigned pageno, curr, next; 603 size_t length; 604 int packet_processed; 605 u16_t eth_type; 606 607 dep = &de_state; 608 609 packet_processed = FALSE; 610 pageno = inb_reg0(dep, DP_BNRY) + 1; 611 if (pageno == dep->de_stoppage) pageno = dep->de_startpage; 612 613 do 614 { 615 outb_reg0(dep, DP_CR, CR_PS_P1 | CR_EXTRA); 616 curr = inb_reg1(dep, DP_CURR); 617 outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA); 618 619 if (curr == pageno) { 620 if (dep->de_flags & DEF_STOPPED) { 621 /* The chip is stopped, and all arrived packets 622 * are delivered. 623 */ 624 dp_reset(dep); 625 } 626 627 return SUSPEND; 628 } 629 630 (dep->de_getblockf)(dep, pageno, (size_t)0, sizeof(header), 631 &header); 632 (dep->de_getblockf)(dep, pageno, sizeof(header) + 633 2*sizeof(netdriver_addr_t), sizeof(eth_type), 634 ð_type); 635 636 length = (header.dr_rbcl | (header.dr_rbch << 8)) - 637 sizeof(dp_rcvhdr_t); 638 next = header.dr_next; 639 if (length < NDEV_ETH_PACKET_MIN || length > max) 640 { 641 printf("%s: packet with strange length arrived: %d\n", 642 netdriver_name(), (int) length); 643 next= curr; 644 } 645 else if (next < dep->de_startpage || next >= dep->de_stoppage) 646 { 647 printf("%s: strange next page\n", netdriver_name()); 648 next= curr; 649 } 650 else if (header.dr_status & RSR_FO) 651 { 652 /* This is very serious, so we issue a warning and 653 * reset the buffers */ 654 printf("%s: fifo overrun, resetting receive buffer\n", 655 netdriver_name()); 656 netdriver_stat_ierror(1); 657 next = curr; 658 } 659 else if (header.dr_status & RSR_PRX) 660 { 661 dp_pkt2user_s(dep, data, pageno, length); 662 663 packet_processed = TRUE; 664 } 665 if (next == dep->de_startpage) 666 outb_reg0(dep, DP_BNRY, dep->de_stoppage - 1); 667 else 668 outb_reg0(dep, DP_BNRY, next - 1); 669 670 pageno = next; 671 } while (!packet_processed); 672 673 return length; 674 } 675 676 /*===========================================================================* 677 * dp_getblock * 678 *===========================================================================*/ 679 static void dp_getblock(dpeth_t *dep, int page, size_t offset, size_t size, 680 void *dst) 681 { 682 offset = page * DP_PAGESIZE + offset; 683 684 memcpy(dst, dep->de_locmem + offset, size); 685 } 686 687 /*===========================================================================* 688 * dp_pio8_getblock * 689 *===========================================================================*/ 690 static void dp_pio8_getblock(dpeth_t *dep, int page, size_t offset, 691 size_t size, void *dst) 692 { 693 offset = page * DP_PAGESIZE + offset; 694 outb_reg0(dep, DP_RBCR0, size & 0xFF); 695 outb_reg0(dep, DP_RBCR1, size >> 8); 696 outb_reg0(dep, DP_RSAR0, offset & 0xFF); 697 outb_reg0(dep, DP_RSAR1, offset >> 8); 698 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA); 699 700 insb(dep->de_data_port, dst, size); 701 } 702 703 /*===========================================================================* 704 * dp_pio16_getblock * 705 *===========================================================================*/ 706 static void dp_pio16_getblock(dpeth_t *dep, int page, size_t offset, 707 size_t size, void *dst) 708 { 709 offset = page * DP_PAGESIZE + offset; 710 outb_reg0(dep, DP_RBCR0, size & 0xFF); 711 outb_reg0(dep, DP_RBCR1, size >> 8); 712 outb_reg0(dep, DP_RSAR0, offset & 0xFF); 713 outb_reg0(dep, DP_RSAR1, offset >> 8); 714 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA); 715 716 assert (!(size & 1)); 717 insw(dep->de_data_port, dst, size); 718 } 719 720 /*===========================================================================* 721 * dp_pkt2user_s * 722 *===========================================================================*/ 723 static void dp_pkt2user_s(dpeth_t *dep, struct netdriver_data *data, int page, 724 size_t length) 725 { 726 unsigned int last, count; 727 728 last = page + (length - 1) / DP_PAGESIZE; 729 if (last >= dep->de_stoppage) 730 { 731 count = (dep->de_stoppage - page) * DP_PAGESIZE - 732 sizeof(dp_rcvhdr_t); 733 734 (dep->de_nic2userf_s)(dep, data, 735 page * DP_PAGESIZE + sizeof(dp_rcvhdr_t), 0, count); 736 (dep->de_nic2userf_s)(dep, data, 737 dep->de_startpage * DP_PAGESIZE, count, length - count); 738 } 739 else 740 { 741 (dep->de_nic2userf_s)(dep, data, 742 page * DP_PAGESIZE + sizeof(dp_rcvhdr_t), 0, length); 743 } 744 } 745 746 /*===========================================================================* 747 * dp_user2nic_s * 748 *===========================================================================*/ 749 static void dp_user2nic_s(dpeth_t *dep, struct netdriver_data *data, 750 int nic_addr, size_t offset, size_t count) 751 { 752 netdriver_copyin(data, offset, dep->de_locmem + nic_addr, count); 753 } 754 755 /*===========================================================================* 756 * dp_pio8_user2nic_s * 757 *===========================================================================*/ 758 static void dp_pio8_user2nic_s(dpeth_t *dep, struct netdriver_data *data, 759 int nic_addr, size_t offset, size_t count) 760 { 761 int i; 762 763 outb_reg0(dep, DP_ISR, ISR_RDC); 764 765 outb_reg0(dep, DP_RBCR0, count & 0xFF); 766 outb_reg0(dep, DP_RBCR1, count >> 8); 767 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF); 768 outb_reg0(dep, DP_RSAR1, nic_addr >> 8); 769 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA); 770 771 netdriver_portoutb(data, offset, dep->de_data_port, count); 772 773 for (i= 0; i<100; i++) 774 { 775 if (inb_reg0(dep, DP_ISR) & ISR_RDC) 776 break; 777 } 778 if (i == 100) 779 { 780 panic("dp8390: remote dma failed to complete"); 781 } 782 } 783 784 /*===========================================================================* 785 * dp_pio16_user2nic_s * 786 *===========================================================================*/ 787 static void dp_pio16_user2nic_s(dpeth_t *dep, struct netdriver_data *data, 788 int nic_addr, size_t offset, size_t count) 789 { 790 size_t ecount; 791 int i; 792 793 ecount= (count+1) & ~1; 794 795 outb_reg0(dep, DP_ISR, ISR_RDC); 796 outb_reg0(dep, DP_RBCR0, ecount & 0xFF); 797 outb_reg0(dep, DP_RBCR1, ecount >> 8); 798 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF); 799 outb_reg0(dep, DP_RSAR1, nic_addr >> 8); 800 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA); 801 802 netdriver_portoutw(data, offset, dep->de_data_port, count); 803 804 for (i= 0; i<100; i++) 805 { 806 if (inb_reg0(dep, DP_ISR) & ISR_RDC) 807 break; 808 } 809 if (i == 100) 810 { 811 panic("dp8390: remote dma failed to complete"); 812 } 813 } 814 815 /*===========================================================================* 816 * dp_nic2user_s * 817 *===========================================================================*/ 818 static void dp_nic2user_s(dpeth_t *dep, struct netdriver_data *data, 819 int nic_addr, size_t offset, size_t count) 820 { 821 netdriver_copyout(data, offset, dep->de_locmem + nic_addr, count); 822 } 823 824 /*===========================================================================* 825 * dp_pio8_nic2user_s * 826 *===========================================================================*/ 827 static void dp_pio8_nic2user_s(dpeth_t *dep, struct netdriver_data *data, 828 int nic_addr, size_t offset, size_t count) 829 { 830 outb_reg0(dep, DP_RBCR0, count & 0xFF); 831 outb_reg0(dep, DP_RBCR1, count >> 8); 832 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF); 833 outb_reg0(dep, DP_RSAR1, nic_addr >> 8); 834 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA); 835 836 netdriver_portinb(data, offset, dep->de_data_port, count); 837 } 838 839 /*===========================================================================* 840 * dp_pio16_nic2user_s * 841 *===========================================================================*/ 842 static void dp_pio16_nic2user_s(dpeth_t *dep, struct netdriver_data *data, 843 int nic_addr, size_t offset, size_t count) 844 { 845 size_t ecount; 846 847 ecount= (count+1) & ~1; 848 849 outb_reg0(dep, DP_RBCR0, ecount & 0xFF); 850 outb_reg0(dep, DP_RBCR1, ecount >> 8); 851 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF); 852 outb_reg0(dep, DP_RSAR1, nic_addr >> 8); 853 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA); 854 855 netdriver_portinw(data, offset, dep->de_data_port, count); 856 } 857 858 /*===========================================================================* 859 * conf_hw * 860 *===========================================================================*/ 861 static void conf_hw(dpeth_t *dep, unsigned int instance) 862 { 863 int confnr; 864 dp_conf_t *dcp; 865 866 /* Pick a default configuration for this instance. */ 867 confnr= MIN(instance, DP_CONF_NR-1); 868 869 dcp= &dp_conf[confnr]; 870 update_conf(dep, dcp, instance); 871 if (!wdeth_probe(dep) && !ne_probe(dep) && !el2_probe(dep)) 872 panic("no ethernet card found at 0x%x\n", dep->de_base_port); 873 874 /* XXX */ if (dep->de_linmem == 0) dep->de_linmem= 0xFFFF0000; 875 } 876 877 /*===========================================================================* 878 * update_conf * 879 *===========================================================================*/ 880 static void update_conf(dpeth_t *dep, dp_conf_t *dcp, unsigned int instance) 881 { 882 long v; 883 static char dpc_fmt[] = "x:d:x:x"; 884 char eckey[16]; 885 886 if (dep->de_pci) 887 { 888 /* PCI device is present */ 889 return; /* Already configured */ 890 } 891 892 strlcpy(eckey, "DPETH0", sizeof(eckey)); 893 eckey[5] += instance; 894 895 /* Get the default settings and modify them from the environment. */ 896 v= dcp->dpc_port; 897 (void) env_parse(eckey, dpc_fmt, 0, &v, 0x0000L, 0xFFFFL); 898 dep->de_base_port= v; 899 900 v= dcp->dpc_irq | DEI_DEFAULT; 901 (void) env_parse(eckey, dpc_fmt, 1, &v, 0L, (long) NR_IRQ_VECTORS - 1); 902 dep->de_irq= v; 903 904 v= dcp->dpc_mem; 905 (void) env_parse(eckey, dpc_fmt, 2, &v, 0L, 0xFFFFFL); 906 dep->de_linmem= v; 907 908 v= 0; 909 (void) env_parse(eckey, dpc_fmt, 3, &v, 0x2000L, 0x8000L); 910 dep->de_ramsize= v; 911 } 912 913 /*===========================================================================* 914 * map_hw_buffer * 915 *===========================================================================*/ 916 static void map_hw_buffer(dpeth_t *dep) 917 { 918 919 if (dep->de_prog_IO) 920 { 921 #if 0 922 printf( 923 "map_hw_buffer: programmed I/O, no need to map buffer\n"); 924 #endif 925 dep->de_locmem = (char *)-dep->de_ramsize; /* trap errors */ 926 return; 927 } 928 929 dep->de_locmem= 930 vm_map_phys(SELF, (void *) dep->de_linmem, dep->de_ramsize); 931 if (dep->de_locmem == MAP_FAILED) 932 panic("map_hw_buffer: vm_map_phys failed"); 933 } 934 935 u8_t inb(port_t port) 936 { 937 int r; 938 u32_t value; 939 940 r= sys_inb(port, &value); 941 if (r != OK) 942 { 943 printf("inb failed for port 0x%x\n", port); 944 panic("sys_inb failed: %d", r); 945 } 946 return value; 947 } 948 949 u16_t inw(port_t port) 950 { 951 int r; 952 u32_t value; 953 954 r= sys_inw(port, &value); 955 if (r != OK) 956 panic("sys_inw failed: %d", r); 957 return (u16_t) value; 958 } 959 960 void outb(port_t port, u8_t value) 961 { 962 int r; 963 964 r= sys_outb(port, value); 965 if (r != OK) 966 panic("sys_outb failed: %d", r); 967 } 968 969 void outw(port_t port, u16_t value) 970 { 971 int r; 972 973 r= sys_outw(port, value); 974 if (r != OK) 975 panic("sys_outw failed: %d", r); 976 } 977 978 static void insb(port_t port, void *buf, size_t size) 979 { 980 int r; 981 982 r= sys_insb(port, SELF, buf, size); 983 if (r != OK) 984 panic("sys_sdevio failed: %d", r); 985 } 986 987 static void insw(port_t port, void *buf, size_t size) 988 { 989 int r; 990 991 r= sys_insw(port, SELF, buf, size); 992 if (r != OK) 993 panic("sys_sdevio failed: %d", r); 994 } 995 996 /* 997 * $PchId: dp8390.c,v 1.25 2005/02/10 17:32:07 philip Exp $ 998 */ 999