Changes in uspace/srv/hw/netif/dp8390/dp8390.c [d8d8bbd:7922dea] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hw/netif/dp8390/dp8390.c
rd8d8bbd r7922dea 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);91 89 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);96 90 static void conf_hw(dpeth_t *dep); 97 91 static void insb(port_t port, void *buf, size_t size); … … 102 96 /* This is the default, try to (re)locate the device. */ 103 97 conf_hw(dep); 104 if ( dep->de_mode == DEM_DISABLED)98 if (!dep->up) 105 99 /* Probe failed, or the device is configured off. */ 106 100 return EXDEV; 107 101 108 if (dep-> de_mode == DEM_ENABLED)102 if (dep->up) 109 103 dp_init(dep); 110 104 … … 112 106 } 113 107 114 int do_init(dpeth_t *dep, int mode) 115 { 116 if (dep->de_mode == DEM_DISABLED) 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) 117 119 /* FIXME: Perhaps call do_probe()? */ 118 120 return EXDEV; 119 121 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; 122 assert(dep->up); 123 assert(dep->enabled); 133 124 134 125 dp_reinit(dep); … … 138 129 void do_stop(dpeth_t *dep) 139 130 { 140 if ((dep->de_mode == DEM_ENABLED) 141 && (dep->de_flags & DEF_ENABLED)) { 131 if ((dep->up) && (dep->enabled)) { 142 132 outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT); 143 (dep->de_stopf)(dep); 144 dep->de_flags = DEF_EMPTY; 145 } 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"); 146 189 } 147 190 … … 151 194 int sendq_head; 152 195 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");196 assert(dep->up); 197 assert(dep->enabled); 198 199 if (dep->send_avail) { 200 fprintf(stderr, "Send already in progress\n"); 158 201 return EBUSY; 159 202 } … … 163 206 if (from_int) 164 207 fprintf(stderr, "dp8390: should not be sending\n"); 165 dep-> de_flags |= DEF_SEND_AVAIL;166 dep-> de_flags &= ~DEF_PACK_SEND;208 dep->send_avail = true; 209 dep->sending = false; 167 210 168 211 return EBUSY; 169 212 } 170 213 171 assert(! (dep->de_flags & DEF_PACK_SEND));214 assert(!dep->sending); 172 215 173 216 void *buf = packet_get_data(packet); … … 179 222 } 180 223 181 (dep->de_user2nicf)(dep, buf, 0,182 dep->de_sendq[sendq_head].sq_sendpage* DP_PAGESIZE, size);224 dp_user2nic(dep, buf, 0, dep->de_sendq[sendq_head].sq_sendpage 225 * DP_PAGESIZE, size); 183 226 dep->de_sendq[sendq_head].sq_filled = true; 184 227 … … 196 239 assert(sendq_head < SENDQ_NR); 197 240 dep->de_sendq_head = sendq_head; 198 199 dep->de_flags |= DEF_PACK_SEND; 241 dep->sending = true; 200 242 201 243 if (from_int) 202 244 return EOK; 203 245 204 dep-> de_flags &= ~DEF_PACK_SEND;246 dep->sending = false; 205 247 206 248 return EOK; … … 213 255 214 256 /* General initialization */ 215 dep->de_flags = DEF_EMPTY; 216 (*dep->de_initf)(dep); 217 218 printf("%s: Ethernet address ", dep->de_name); 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 "); 219 264 for (i = 0; i < 6; i++) 220 265 printf("%x%c", dep->de_address.ea_addr[i], i < 5 ? ':' : '\n'); … … 240 285 241 286 /* Step 4: */ 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; 287 dp_rcr_reg = RCR_AB; /* Enable broadcasts */ 252 288 253 289 outb_reg0(dep, DP_RCR, dp_rcr_reg); … … 300 336 301 337 /* Finish the initialization. */ 302 dep-> de_flags |= DEF_ENABLED;338 dep->enabled = true; 303 339 for (i = 0; i < dep->de_sendq_nr; i++) 304 340 dep->de_sendq[i].sq_filled= 0; … … 306 342 dep->de_sendq_head = 0; 307 343 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 }318 344 } 319 345 … … 324 350 outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA); 325 351 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; 352 /* Enable broadcasts */ 353 dp_rcr_reg = RCR_AB; 336 354 337 355 outb_reg0(dep, DP_RCR, dp_rcr_reg); … … 371 389 dep->de_sendq[i].sq_filled = 0; 372 390 373 dep-> de_flags &= ~DEF_SEND_AVAIL;374 dep-> de_flags &= ~DEF_STOPPED;391 dep->send_avail = false; 392 dep->stopped = false; 375 393 } 376 394 377 395 static uint8_t isr_acknowledge(dpeth_t *dep) 378 396 { 379 uint8_t isr = inb_reg0(dep, DP_ISR) & 0x7f;397 uint8_t isr = inb_reg0(dep, DP_ISR); 380 398 if (isr != 0) 381 399 outb_reg0(dep, DP_ISR, isr); … … 389 407 int size, sendq_tail; 390 408 391 if (!(dep->de_flags & DEF_ENABLED)) 392 fprintf(stderr, "dp8390: got premature interrupt\n"); 393 394 for (; isr != 0; isr = isr_acknowledge(dep)) { 409 for (; (isr & 0x7f) != 0; isr = isr_acknowledge(dep)) { 395 410 if (isr & (ISR_PTX | ISR_TXE)) { 396 411 if (isr & ISR_TXE) … … 412 427 413 428 if ((tsr & TSR_FU) && (++dep->de_stat.ets_fifoUnder <= 10)) 414 printf(" %s: fifo underrun\n", dep->de_name);429 printf("FIFO underrun\n"); 415 430 416 431 if ((tsr & TSR_CDH) && (++dep->de_stat.ets_CDheartbeat <= 10)) 417 printf(" %s: CD heart beat failure\n", dep->de_name);432 printf("CD heart beat failure\n"); 418 433 419 434 if (tsr & TSR_OWC) … … 424 439 425 440 if (!(dep->de_sendq[sendq_tail].sq_filled)) { 426 /* Or hardware bug? */ 427 printf("%s: transmit interrupt, but not sending\n", dep->de_name); 441 printf("PTX interrupt, but no frame to send\n"); 428 442 continue; 429 443 } 430 444 431 dep->de_sendq[sendq_tail].sq_filled = 0;445 dep->de_sendq[sendq_tail].sq_filled = false; 432 446 433 447 if (++sendq_tail == dep->de_sendq_nr) … … 445 459 } 446 460 447 dep-> de_flags &= ~DEF_SEND_AVAIL;461 dep->send_avail = false; 448 462 } 449 463 … … 469 483 if (isr & ISR_RST) { 470 484 /* 471 * This means we got an interrupt but the ethernet 472 * chip is shutdown. We set the flag DEF_STOPPED,485 * This means we got an interrupt but the ethernet 486 * chip is shutdown. We set the flag 'stopped' 473 487 * and continue processing arrived packets. When the 474 488 * receive buffer is empty, we reset the dp8390. 475 489 */ 476 dep-> de_flags |= DEF_STOPPED;490 dep->stopped = true; 477 491 break; 478 492 } 479 493 } 480 494 481 if ( (dep->de_flags & DEF_STOPPED) == DEF_STOPPED) {495 if (dep->stopped) { 482 496 /* 483 * The chip is stopped, and all arrived packets484 * are delivered.497 * The chip is stopped, and all arrived 498 * frames are delivered. 485 499 */ 486 500 dp_reset(dep); 487 501 } 488 502 489 dep->de_flags &= ~DEF_PACK_SEND; 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); 490 521 } 491 522 … … 511 542 break; 512 543 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); 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); 515 547 516 548 length = (header.dr_rbcl | (header.dr_rbch << 8)) - sizeof(dp_rcvhdr_t); 517 549 next = header.dr_next; 518 550 if ((length < ETH_MIN_PACK_SIZE) || (length > ETH_MAX_PACK_SIZE_TAGGED)) { 519 printf(" %s: packet with strange length arrived: %d\n", dep->de_name, (int)length);551 printf("Packet with strange length arrived: %zu\n", length); 520 552 next= curr; 521 553 } else if ((next < dep->de_startpage) || (next >= dep->de_stoppage)) { 522 printf(" %s: strange next page\n", dep->de_name);554 printf("Strange next page\n"); 523 555 next= curr; 524 556 } else if (header.dr_status & RSR_FO) { … … 527 559 * reset the buffers 528 560 */ 529 printf(" %s: fifo overrun, resetting receive buffer\n", dep->de_name);561 printf("FIFO overrun, resetting receive buffer\n"); 530 562 dep->de_stat.ets_fifoOver++; 531 563 next = curr; 532 } else if ((header.dr_status & RSR_PRX) && (dep-> de_flags & DEF_ENABLED)) {564 } else if ((header.dr_status & RSR_PRX) && (dep->enabled)) { 533 565 r = dp_pkt2user(nil_phone, device_id, dep, pageno, length); 534 566 if (r != EOK) … … 548 580 } 549 581 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); 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); 557 596 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA); 558 597 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); 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); 574 616 } 575 617 … … 589 631 count = (dep->de_stoppage - page) * DP_PAGESIZE - sizeof(dp_rcvhdr_t); 590 632 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,633 dp_nic2user(dep, page * DP_PAGESIZE + sizeof(dp_rcvhdr_t), 634 buf, 0, count); 635 dp_nic2user(dep, dep->de_startpage * DP_PAGESIZE, 594 636 buf, count, length - count); 595 637 } else { 596 (dep->de_nic2userf)(dep, page * DP_PAGESIZE +597 sizeof(dp_rcvhdr_t),buf, 0, length);638 dp_nic2user(dep, page * DP_PAGESIZE + sizeof(dp_rcvhdr_t), 639 buf, 0, length); 598 640 } 599 641 … … 603 645 } 604 646 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 708 647 static void conf_hw(dpeth_t *dep) 709 648 { 710 649 if (!ne_probe(dep)) { 711 printf("%s: No ethernet card found at %#lx\n", 712 dep->de_name, dep->de_base_port); 713 dep->de_mode= DEM_DISABLED; 650 printf("No ethernet card found at %#lx\n", dep->de_base_port); 651 dep->up = false; 714 652 return; 715 653 } 716 654 717 dep->de_mode = DEM_ENABLED; 718 dep->de_flags = DEF_EMPTY; 655 dep->up = true; 656 dep->enabled = false; 657 dep->stopped = false; 658 dep->sending = false; 659 dep->send_avail = false; 719 660 } 720 661
Note:
See TracChangeset
for help on using the changeset viewer.