Changes in uspace/srv/hw/netif/dp8390/dp8390.c [7922dea:d8d8bbd] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hw/netif/dp8390/dp8390.c
r7922dea rd8d8bbd 87 87 static void dp_reset(dpeth_t *dep); 88 88 static void dp_recv(int nil_phone, device_id_t device_id, dpeth_t *dep); 89 static void dp_pio8_getblock(dpeth_t *dep, int page, size_t offset, size_t size, void *dst); 90 static void dp_pio16_getblock(dpeth_t *dep, int page, size_t offset, size_t size, void *dst); 89 91 static int dp_pkt2user(int nil_phone, device_id_t device_id, dpeth_t *dep, int page, int length); 92 static void dp_pio8_user2nic(dpeth_t *dep, void *buf, size_t offset, int nic_addr, size_t size); 93 static void dp_pio16_user2nic(dpeth_t *dep, void *buf, size_t offset, int nic_addr, size_t size); 94 static void dp_pio8_nic2user(dpeth_t *dep, int nic_addr, void *buf, size_t offset, size_t size); 95 static void dp_pio16_nic2user(dpeth_t *dep, int nic_addr, void *buf, size_t offset, size_t size); 90 96 static void conf_hw(dpeth_t *dep); 91 97 static void insb(port_t port, void *buf, size_t size); … … 96 102 /* This is the default, try to (re)locate the device. */ 97 103 conf_hw(dep); 98 if ( !dep->up)104 if (dep->de_mode == DEM_DISABLED) 99 105 /* Probe failed, or the device is configured off. */ 100 106 return EXDEV; 101 107 102 if (dep-> up)108 if (dep->de_mode == DEM_ENABLED) 103 109 dp_init(dep); 104 110 … … 106 112 } 107 113 108 /** Initialize and/or start the network interface. 109 * 110 * @param[in,out] dep The network interface structure. 111 * 112 * @return EOK on success. 113 * @return EXDEV if the network interface is disabled. 114 * 115 */ 116 int do_init(dpeth_t *dep) 117 { 118 if (!dep->up) 114 int do_init(dpeth_t *dep, int mode) 115 { 116 if (dep->de_mode == DEM_DISABLED) 119 117 /* FIXME: Perhaps call do_probe()? */ 120 118 return EXDEV; 121 119 122 assert(dep->up); 123 assert(dep->enabled); 120 assert(dep->de_mode == DEM_ENABLED); 121 assert(dep->de_flags & DEF_ENABLED); 122 123 dep->de_flags &= ~(DEF_PROMISC | DEF_MULTI | DEF_BROAD); 124 125 if (mode &DL_PROMISC_REQ) 126 dep->de_flags |= DEF_PROMISC | DEF_MULTI | DEF_BROAD; 127 128 if (mode &DL_MULTI_REQ) 129 dep->de_flags |= DEF_MULTI; 130 131 if (mode &DL_BROAD_REQ) 132 dep->de_flags |= DEF_BROAD; 124 133 125 134 dp_reinit(dep); … … 129 138 void do_stop(dpeth_t *dep) 130 139 { 131 if ((dep->up) && (dep->enabled)) { 140 if ((dep->de_mode == DEM_ENABLED) 141 && (dep->de_flags & DEF_ENABLED)) { 132 142 outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT); 133 ne_stop(dep); 134 135 dep->enabled = false; 136 dep->stopped = false; 137 dep->sending = false; 138 dep->send_avail = false; 139 } 140 } 141 142 static void dp_user2nic(dpeth_t *dep, void *buf, size_t offset, int nic_addr, size_t size) 143 { 144 size_t ecount = size & ~1; 145 146 outb_reg0(dep, DP_ISR, ISR_RDC); 147 148 if (dep->de_16bit) { 149 outb_reg0(dep, DP_RBCR0, ecount & 0xff); 150 outb_reg0(dep, DP_RBCR1, ecount >> 8); 151 } else { 152 outb_reg0(dep, DP_RBCR0, size & 0xff); 153 outb_reg0(dep, DP_RBCR1, size >> 8); 154 } 155 156 outb_reg0(dep, DP_RSAR0, nic_addr & 0xff); 157 outb_reg0(dep, DP_RSAR1, nic_addr >> 8); 158 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA); 159 160 if (dep->de_16bit) { 161 void *ptr = buf + offset; 162 163 if (ecount != 0) { 164 outsw(dep->de_data_port, ptr, ecount); 165 size -= ecount; 166 offset += ecount; 167 ptr += ecount; 168 } 169 170 if (size) { 171 assert(size == 1); 172 173 uint16_t two_bytes; 174 175 memcpy(&(((uint8_t *) &two_bytes)[0]), ptr, 1); 176 outw(dep->de_data_port, two_bytes); 177 } 178 } else 179 outsb(dep->de_data_port, buf + offset, size); 180 181 unsigned int i; 182 for (i = 0; i < 100; i++) { 183 if (inb_reg0(dep, DP_ISR) & ISR_RDC) 184 break; 185 } 186 187 if (i == 100) 188 fprintf(stderr, "Remote DMA failed to complete\n"); 143 (dep->de_stopf)(dep); 144 dep->de_flags = DEF_EMPTY; 145 } 189 146 } 190 147 … … 194 151 int sendq_head; 195 152 196 assert(dep-> up);197 assert(dep-> enabled);198 199 if (dep-> send_avail) {200 fprintf(stderr, " Send already in progress\n");153 assert(dep->de_mode == DEM_ENABLED); 154 assert(dep->de_flags & DEF_ENABLED); 155 156 if (dep->de_flags & DEF_SEND_AVAIL) { 157 fprintf(stderr, "dp8390: send already in progress\n"); 201 158 return EBUSY; 202 159 } … … 206 163 if (from_int) 207 164 fprintf(stderr, "dp8390: should not be sending\n"); 208 dep-> send_avail = true;209 dep-> sending = false;165 dep->de_flags |= DEF_SEND_AVAIL; 166 dep->de_flags &= ~DEF_PACK_SEND; 210 167 211 168 return EBUSY; 212 169 } 213 170 214 assert(! dep->sending);171 assert(!(dep->de_flags & DEF_PACK_SEND)); 215 172 216 173 void *buf = packet_get_data(packet); … … 222 179 } 223 180 224 dp_user2nic(dep, buf, 0, dep->de_sendq[sendq_head].sq_sendpage225 * DP_PAGESIZE, size);181 (dep->de_user2nicf)(dep, buf, 0, 182 dep->de_sendq[sendq_head].sq_sendpage * DP_PAGESIZE, size); 226 183 dep->de_sendq[sendq_head].sq_filled = true; 227 184 … … 239 196 assert(sendq_head < SENDQ_NR); 240 197 dep->de_sendq_head = sendq_head; 241 dep->sending = true; 198 199 dep->de_flags |= DEF_PACK_SEND; 242 200 243 201 if (from_int) 244 202 return EOK; 245 203 246 dep-> sending = false;204 dep->de_flags &= ~DEF_PACK_SEND; 247 205 248 206 return EOK; … … 255 213 256 214 /* General initialization */ 257 dep->enabled = false; 258 dep->stopped = false; 259 dep->sending = false; 260 dep->send_avail = false; 261 ne_init(dep); 262 263 printf("Ethernet address "); 215 dep->de_flags = DEF_EMPTY; 216 (*dep->de_initf)(dep); 217 218 printf("%s: Ethernet address ", dep->de_name); 264 219 for (i = 0; i < 6; i++) 265 220 printf("%x%c", dep->de_address.ea_addr[i], i < 5 ? ':' : '\n'); … … 285 240 286 241 /* Step 4: */ 287 dp_rcr_reg = RCR_AB; /* Enable broadcasts */ 242 dp_rcr_reg = 0; 243 244 if (dep->de_flags & DEF_PROMISC) 245 dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM; 246 247 if (dep->de_flags & DEF_BROAD) 248 dp_rcr_reg |= RCR_AB; 249 250 if (dep->de_flags & DEF_MULTI) 251 dp_rcr_reg |= RCR_AM; 288 252 289 253 outb_reg0(dep, DP_RCR, dp_rcr_reg); … … 336 300 337 301 /* Finish the initialization. */ 338 dep-> enabled = true;302 dep->de_flags |= DEF_ENABLED; 339 303 for (i = 0; i < dep->de_sendq_nr; i++) 340 304 dep->de_sendq[i].sq_filled= 0; … … 342 306 dep->de_sendq_head = 0; 343 307 dep->de_sendq_tail = 0; 308 309 if (dep->de_16bit) { 310 dep->de_user2nicf= dp_pio16_user2nic; 311 dep->de_nic2userf= dp_pio16_nic2user; 312 dep->de_getblockf= dp_pio16_getblock; 313 } else { 314 dep->de_user2nicf= dp_pio8_user2nic; 315 dep->de_nic2userf= dp_pio8_nic2user; 316 dep->de_getblockf= dp_pio8_getblock; 317 } 344 318 } 345 319 … … 350 324 outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA); 351 325 352 /* Enable broadcasts */ 353 dp_rcr_reg = RCR_AB; 326 dp_rcr_reg = 0; 327 328 if (dep->de_flags & DEF_PROMISC) 329 dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM; 330 331 if (dep->de_flags & DEF_BROAD) 332 dp_rcr_reg |= RCR_AB; 333 334 if (dep->de_flags & DEF_MULTI) 335 dp_rcr_reg |= RCR_AM; 354 336 355 337 outb_reg0(dep, DP_RCR, dp_rcr_reg); … … 389 371 dep->de_sendq[i].sq_filled = 0; 390 372 391 dep-> send_avail = false;392 dep-> stopped = false;373 dep->de_flags &= ~DEF_SEND_AVAIL; 374 dep->de_flags &= ~DEF_STOPPED; 393 375 } 394 376 395 377 static uint8_t isr_acknowledge(dpeth_t *dep) 396 378 { 397 uint8_t isr = inb_reg0(dep, DP_ISR) ;379 uint8_t isr = inb_reg0(dep, DP_ISR) & 0x7f; 398 380 if (isr != 0) 399 381 outb_reg0(dep, DP_ISR, isr); … … 407 389 int size, sendq_tail; 408 390 409 for (; (isr & 0x7f) != 0; isr = isr_acknowledge(dep)) { 391 if (!(dep->de_flags & DEF_ENABLED)) 392 fprintf(stderr, "dp8390: got premature interrupt\n"); 393 394 for (; isr != 0; isr = isr_acknowledge(dep)) { 410 395 if (isr & (ISR_PTX | ISR_TXE)) { 411 396 if (isr & ISR_TXE) … … 427 412 428 413 if ((tsr & TSR_FU) && (++dep->de_stat.ets_fifoUnder <= 10)) 429 printf(" FIFO underrun\n");414 printf("%s: fifo underrun\n", dep->de_name); 430 415 431 416 if ((tsr & TSR_CDH) && (++dep->de_stat.ets_CDheartbeat <= 10)) 432 printf(" CD heart beat failure\n");417 printf("%s: CD heart beat failure\n", dep->de_name); 433 418 434 419 if (tsr & TSR_OWC) … … 439 424 440 425 if (!(dep->de_sendq[sendq_tail].sq_filled)) { 441 printf("PTX interrupt, but no frame to send\n"); 426 /* Or hardware bug? */ 427 printf("%s: transmit interrupt, but not sending\n", dep->de_name); 442 428 continue; 443 429 } 444 430 445 dep->de_sendq[sendq_tail].sq_filled = false;431 dep->de_sendq[sendq_tail].sq_filled = 0; 446 432 447 433 if (++sendq_tail == dep->de_sendq_nr) … … 459 445 } 460 446 461 dep-> send_avail = false;447 dep->de_flags &= ~DEF_SEND_AVAIL; 462 448 } 463 449 … … 483 469 if (isr & ISR_RST) { 484 470 /* 485 * This means we got an interrupt but the ethernet 486 * chip is shutdown. We set the flag 'stopped'471 * This means we got an interrupt but the ethernet 472 * chip is shutdown. We set the flag DEF_STOPPED, 487 473 * and continue processing arrived packets. When the 488 474 * receive buffer is empty, we reset the dp8390. 489 475 */ 490 dep-> stopped = true;476 dep->de_flags |= DEF_STOPPED; 491 477 break; 492 478 } 493 479 } 494 480 495 if ( dep->stopped) {481 if ((dep->de_flags & DEF_STOPPED) == DEF_STOPPED) { 496 482 /* 497 * The chip is stopped, and all arrived 498 * framesare delivered.483 * The chip is stopped, and all arrived packets 484 * are delivered. 499 485 */ 500 486 dp_reset(dep); 501 487 } 502 488 503 dep->sending = false; 504 } 505 506 static void dp_getblock(dpeth_t *dep, int page, size_t offset, size_t size, void *dst) 507 { 508 offset = page * DP_PAGESIZE + offset; 509 510 outb_reg0(dep, DP_RBCR0, size & 0xff); 511 outb_reg0(dep, DP_RBCR1, size >> 8); 512 outb_reg0(dep, DP_RSAR0, offset & 0xff); 513 outb_reg0(dep, DP_RSAR1, offset >> 8); 514 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA); 515 516 if (dep->de_16bit) { 517 assert((size % 2) == 0); 518 insw(dep->de_data_port, dst, size); 519 } else 520 insb(dep->de_data_port, dst, size); 489 dep->de_flags &= ~DEF_PACK_SEND; 521 490 } 522 491 … … 542 511 break; 543 512 544 dp_getblock(dep, pageno, (size_t) 0, sizeof(header), &header); 545 dp_getblock(dep, pageno, sizeof(header) + 546 2 * sizeof(ether_addr_t), sizeof(eth_type), ð_type); 513 (dep->de_getblockf)(dep, pageno, (size_t) 0, sizeof(header), &header); 514 (dep->de_getblockf)(dep, pageno, sizeof(header) + 2 * sizeof(ether_addr_t), sizeof(eth_type), ð_type); 547 515 548 516 length = (header.dr_rbcl | (header.dr_rbch << 8)) - sizeof(dp_rcvhdr_t); 549 517 next = header.dr_next; 550 518 if ((length < ETH_MIN_PACK_SIZE) || (length > ETH_MAX_PACK_SIZE_TAGGED)) { 551 printf(" Packet with strange length arrived: %zu\n",length);519 printf("%s: packet with strange length arrived: %d\n", dep->de_name, (int) length); 552 520 next= curr; 553 521 } else if ((next < dep->de_startpage) || (next >= dep->de_stoppage)) { 554 printf(" Strange next page\n");522 printf("%s: strange next page\n", dep->de_name); 555 523 next= curr; 556 524 } else if (header.dr_status & RSR_FO) { … … 559 527 * reset the buffers 560 528 */ 561 printf(" FIFO overrun, resetting receive buffer\n");529 printf("%s: fifo overrun, resetting receive buffer\n", dep->de_name); 562 530 dep->de_stat.ets_fifoOver++; 563 531 next = curr; 564 } else if ((header.dr_status & RSR_PRX) && (dep-> enabled)) {532 } else if ((header.dr_status & RSR_PRX) && (dep->de_flags & DEF_ENABLED)) { 565 533 r = dp_pkt2user(nil_phone, device_id, dep, pageno, length); 566 534 if (r != EOK) … … 580 548 } 581 549 582 static void dp_nic2user(dpeth_t *dep, int nic_addr, void *buf, size_t offset, size_t size) 583 { 584 size_t ecount = size & ~1; 585 586 if (dep->de_16bit) { 587 outb_reg0(dep, DP_RBCR0, ecount & 0xFF); 588 outb_reg0(dep, DP_RBCR1, ecount >> 8); 589 } else { 590 outb_reg0(dep, DP_RBCR0, size & 0xff); 591 outb_reg0(dep, DP_RBCR1, size >> 8); 592 } 593 594 outb_reg0(dep, DP_RSAR0, nic_addr & 0xff); 595 outb_reg0(dep, DP_RSAR1, nic_addr >> 8); 550 static void dp_pio8_getblock(dpeth_t *dep, int page, size_t offset, size_t size, void *dst) 551 { 552 offset = page * DP_PAGESIZE + offset; 553 outb_reg0(dep, DP_RBCR0, size &0xFF); 554 outb_reg0(dep, DP_RBCR1, size >> 8); 555 outb_reg0(dep, DP_RSAR0, offset &0xFF); 556 outb_reg0(dep, DP_RSAR1, offset >> 8); 596 557 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA); 597 558 598 if (dep->de_16bit) { 599 void *ptr = buf + offset; 600 601 if (ecount != 0) { 602 insw(dep->de_data_port, ptr, ecount); 603 size -= ecount; 604 offset += ecount; 605 ptr += ecount; 606 } 607 608 if (size) { 609 assert(size == 1); 610 611 uint16_t two_bytes = inw(dep->de_data_port); 612 memcpy(ptr, &(((uint8_t *) &two_bytes)[0]), 1); 613 } 614 } else 615 insb(dep->de_data_port, buf + offset, size); 559 insb(dep->de_data_port, dst, size); 560 } 561 562 static void dp_pio16_getblock(dpeth_t *dep, int page, size_t offset, size_t size, void *dst) 563 { 564 offset = page * DP_PAGESIZE + offset; 565 outb_reg0(dep, DP_RBCR0, size &0xFF); 566 outb_reg0(dep, DP_RBCR1, size >> 8); 567 outb_reg0(dep, DP_RSAR0, offset &0xFF); 568 outb_reg0(dep, DP_RSAR1, offset >> 8); 569 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA); 570 571 assert(!(size & 1)); 572 573 insw(dep->de_data_port, dst, size); 616 574 } 617 575 … … 631 589 count = (dep->de_stoppage - page) * DP_PAGESIZE - sizeof(dp_rcvhdr_t); 632 590 633 dp_nic2user(dep, page * DP_PAGESIZE + sizeof(dp_rcvhdr_t),634 buf, 0, count);635 dp_nic2user(dep, dep->de_startpage * DP_PAGESIZE,591 (dep->de_nic2userf)(dep, page * DP_PAGESIZE + 592 sizeof(dp_rcvhdr_t), buf, 0, count); 593 (dep->de_nic2userf)(dep, dep->de_startpage * DP_PAGESIZE, 636 594 buf, count, length - count); 637 595 } else { 638 dp_nic2user(dep, page * DP_PAGESIZE + sizeof(dp_rcvhdr_t),639 buf, 0, length);596 (dep->de_nic2userf)(dep, page * DP_PAGESIZE + 597 sizeof(dp_rcvhdr_t), buf, 0, length); 640 598 } 641 599 … … 645 603 } 646 604 605 static void dp_pio8_user2nic(dpeth_t *dep, void *buf, size_t offset, int nic_addr, size_t size) 606 { 607 outb_reg0(dep, DP_ISR, ISR_RDC); 608 609 outb_reg0(dep, DP_RBCR0, size & 0xFF); 610 outb_reg0(dep, DP_RBCR1, size >> 8); 611 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF); 612 outb_reg0(dep, DP_RSAR1, nic_addr >> 8); 613 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA); 614 615 outsb(dep->de_data_port, buf + offset, size); 616 617 unsigned int i; 618 for (i = 0; i < 100; i++) { 619 if (inb_reg0(dep, DP_ISR) & ISR_RDC) 620 break; 621 } 622 623 if (i == 100) 624 fprintf(stderr, "dp8390: remote DMA failed to complete\n"); 625 } 626 627 static void dp_pio16_user2nic(dpeth_t *dep, void *buf, size_t offset, int nic_addr, size_t size) 628 { 629 void *vir_user; 630 size_t ecount; 631 uint16_t two_bytes; 632 633 ecount = size & ~1; 634 635 outb_reg0(dep, DP_ISR, ISR_RDC); 636 outb_reg0(dep, DP_RBCR0, ecount & 0xFF); 637 outb_reg0(dep, DP_RBCR1, ecount >> 8); 638 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF); 639 outb_reg0(dep, DP_RSAR1, nic_addr >> 8); 640 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA); 641 642 vir_user = buf + offset; 643 if (ecount != 0) { 644 outsw(dep->de_data_port, vir_user, ecount); 645 size -= ecount; 646 offset += ecount; 647 vir_user += ecount; 648 } 649 650 if (size) { 651 assert(size == 1); 652 653 memcpy(&(((uint8_t *) &two_bytes)[0]), vir_user, 1); 654 outw(dep->de_data_port, two_bytes); 655 } 656 657 unsigned int i; 658 for (i = 0; i < 100; i++) { 659 if (inb_reg0(dep, DP_ISR) & ISR_RDC) 660 break; 661 } 662 663 if (i == 100) 664 fprintf(stderr, "dp8390: remote dma failed to complete\n"); 665 } 666 667 static void dp_pio8_nic2user(dpeth_t *dep, int nic_addr, void *buf, size_t offset, size_t size) 668 { 669 outb_reg0(dep, DP_RBCR0, size & 0xFF); 670 outb_reg0(dep, DP_RBCR1, size >> 8); 671 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF); 672 outb_reg0(dep, DP_RSAR1, nic_addr >> 8); 673 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA); 674 675 insb(dep->de_data_port, buf + offset, size); 676 } 677 678 static void dp_pio16_nic2user(dpeth_t *dep, int nic_addr, void *buf, size_t offset, size_t size) 679 { 680 void *vir_user; 681 size_t ecount; 682 uint16_t two_bytes; 683 684 ecount = size & ~1; 685 686 outb_reg0(dep, DP_RBCR0, ecount & 0xFF); 687 outb_reg0(dep, DP_RBCR1, ecount >> 8); 688 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF); 689 outb_reg0(dep, DP_RSAR1, nic_addr >> 8); 690 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA); 691 692 vir_user = buf + offset; 693 if (ecount != 0) { 694 insw(dep->de_data_port, vir_user, ecount); 695 size -= ecount; 696 offset += ecount; 697 vir_user += ecount; 698 } 699 700 if (size) { 701 assert(size == 1); 702 703 two_bytes = inw(dep->de_data_port); 704 memcpy(vir_user, &(((uint8_t *) &two_bytes)[0]), 1); 705 } 706 } 707 647 708 static void conf_hw(dpeth_t *dep) 648 709 { 649 710 if (!ne_probe(dep)) { 650 printf("No ethernet card found at %#lx\n", dep->de_base_port); 651 dep->up = false; 711 printf("%s: No ethernet card found at %#lx\n", 712 dep->de_name, dep->de_base_port); 713 dep->de_mode= DEM_DISABLED; 652 714 return; 653 715 } 654 716 655 dep->up = true; 656 dep->enabled = false; 657 dep->stopped = false; 658 dep->sending = false; 659 dep->send_avail = false; 717 dep->de_mode = DEM_ENABLED; 718 dep->de_flags = DEF_EMPTY; 660 719 } 661 720
Note:
See TracChangeset
for help on using the changeset viewer.