Changeset 59b3095 in mainline for uspace/drv/nic/rtl8169/driver.c
- Timestamp:
- 2014-06-02T20:53:10Z (10 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- be971233
- Parents:
- 0764cc8a
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/nic/rtl8169/driver.c
r0764cc8a r59b3095 209 209 return EINVAL; 210 210 }; 211 211 212 if (hw_resources->io_ranges.count != 1) { 212 213 ddf_msg(LVL_ERROR, "%s device: unexpected io ranges count", ddf_dev_get_name(dev)); … … 237 238 rc = dmamem_map_anonymous(TX_RING_SIZE, DMAMEM_4GiB, 238 239 AS_AREA_READ | AS_AREA_WRITE, 0, &rtl8169->tx_ring_phys, 239 &rtl8169->tx_ring_virt);240 (void **)&rtl8169->tx_ring); 240 241 241 242 if (rc != EOK) … … 245 246 rc = dmamem_map_anonymous(RX_RING_SIZE, DMAMEM_4GiB, 246 247 AS_AREA_READ | AS_AREA_WRITE, 0, &rtl8169->rx_ring_phys, 247 &rtl8169->rx_ring_virt);248 (void **)&rtl8169->rx_ring); 248 249 249 250 if (rc != EOK) … … 253 254 rc = dmamem_map_anonymous(TX_BUFFERS_SIZE, DMAMEM_4GiB, 254 255 AS_AREA_READ | AS_AREA_WRITE, 0, &rtl8169->tx_buff_phys, 255 &rtl8169->tx_buff _virt);256 &rtl8169->tx_buff); 256 257 257 258 if (rc != EOK) … … 261 262 rc = dmamem_map_anonymous(RX_BUFFERS_SIZE, DMAMEM_4GiB, 262 263 AS_AREA_READ | AS_AREA_WRITE, 0, &rtl8169->rx_buff_phys, 263 &rtl8169->rx_buff _virt);264 &rtl8169->rx_buff); 264 265 265 266 if (rc != EOK) 266 267 return rc; 268 269 return EOK; 267 270 } 268 271 … … 521 524 rtl8169_reset(rtl8169); 522 525 526 /* Allocate buffers */ 527 rtl8169_allocate_buffers(rtl8169); 528 529 /* Write address of descriptor as start of TX ring */ 530 pio_write_32(rtl8169->regs + TNPDS, rtl8169->tx_ring_phys & 0xffffffff); 531 pio_write_32(rtl8169->regs + TNPDS + 4, (rtl8169->tx_ring_phys >> 32) & 0xffffffff); 532 rtl8169->tx_head = 0; 533 rtl8169->tx_tail = 0; 534 rtl8169->tx_ring[15].control = CONTROL_EOR; 535 523 536 /* Enable TX and RX */ 524 537 uint8_t cr = pio_read_8(rtl8169->regs + CR); … … 594 607 } 595 608 596 609 static void rtl8169_transmit_done(ddf_dev_t *dev) 610 { 611 unsigned int tail, head; 612 nic_t *nic_data = nic_get_from_ddf_dev(dev); 613 rtl8169_t *rtl8169 = nic_get_specific(nic_data); 614 rtl8169_descr_t *descr; 615 616 ddf_msg(LVL_NOTE, "rtl8169_transmit_done()"); 617 618 fibril_mutex_lock(&rtl8169->tx_lock); 619 620 head = rtl8169->tx_head; 621 tail = rtl8169->tx_tail; 622 623 while (tail != head) { 624 descr = &rtl8169->tx_ring[tail]; 625 tail = (tail + 1) % TX_BUFFERS_COUNT; 626 627 ddf_msg(LVL_NOTE, "TX status for descr %d: 0x%08x", tail, descr->control); 628 } 629 630 rtl8169->tx_tail = tail; 631 632 fibril_mutex_unlock(&rtl8169->tx_lock); 633 } 597 634 598 635 static void rtl8169_irq_handler(ddf_dev_t *dev, ipc_callid_t iid, … … 601 638 assert(dev); 602 639 assert(icall); 603 604 ddf_msg(LVL_NOTE, "rtl8169_irq_handler()");605 640 606 641 uint16_t isr = (uint16_t) IPC_GET_ARG2(*icall); … … 608 643 rtl8169_t *rtl8169 = nic_get_specific(nic_data); 609 644 645 //ddf_msg(LVL_NOTE, "rtl8169_irq_handler(): isr=0x%04x", isr); 646 610 647 /* Packet underrun or link change */ 611 648 if (isr & INT_PUN) 612 rtl8169_link_change(dev); 613 649 rtl8169_link_change(dev); 650 651 /* Frame(s) successfully transmitted */ 652 if (isr & INT_TOK) 653 rtl8169_transmit_done(dev); 654 655 /* Transmit error */ 656 if (isr & INT_TER) 657 rtl8169_transmit_done(dev); 658 659 if (isr & INT_SERR) 660 ddf_msg(LVL_ERROR, "System error interrupt"); 661 662 if (isr & INT_TDU) 663 ddf_msg(LVL_ERROR, "Transmit descriptor unavailable"); 664 665 if (isr & INT_RER) 666 ddf_msg(LVL_NOTE, "RX error interrupt"); 667 668 if (isr & INT_ROK) 669 ddf_msg(LVL_NOTE, "RX OK interrupt"); 670 671 pio_write_16(rtl8169->regs + ISR, 0xffff); 614 672 pio_write_16(rtl8169->regs + IMR, 0xffff); 615 673 } … … 617 675 static void rtl8169_send_frame(nic_t *nic_data, void *data, size_t size) 618 676 { 619 677 rtl8169_descr_t *descr, *prev; 678 unsigned int head, tail; 679 void *buff; 680 uintptr_t buff_phys; 681 rtl8169_t *rtl8169 = nic_get_specific(nic_data); 682 683 if (size > RTL8169_FRAME_MAX_LENGTH) { 684 ddf_msg(LVL_ERROR, "Send frame: frame too long, %zu bytes", 685 size); 686 nic_report_send_error(nic_data, NIC_SEC_OTHER, 1); 687 } 688 689 fibril_mutex_lock(&rtl8169->tx_lock); 690 691 ddf_msg(LVL_NOTE, "send_frame()"); 692 ddf_msg(LVL_NOTE, "tx ring virtual at %p", rtl8169->tx_ring); 693 ddf_msg(LVL_NOTE, "tx ring physical at 0x%08lx", rtl8169->tx_ring_phys); 694 ddf_msg(LVL_NOTE, "tx_head=%d tx_tail=%d", rtl8169->tx_head, rtl8169->tx_tail); 695 696 head = rtl8169->tx_head; 697 tail = rtl8169->tx_tail; 698 699 if ((tail + 1) % TX_BUFFERS_COUNT == head) { 700 /* Queue is full */ 701 nic_set_tx_busy(nic_data, 1); 702 } 703 704 /* Calculate address of next free buffer and descriptor */ 705 buff = rtl8169->tx_buff + (BUFFER_SIZE * head); 706 buff_phys = rtl8169->tx_buff_phys + (BUFFER_SIZE * head); 707 708 /* Copy frame */ 709 memcpy(buff, data, size); 710 711 /* Setup descriptor */ 712 descr = &rtl8169->tx_ring[head]; 713 prev = &rtl8169->tx_ring[(head - 1) % TX_BUFFERS_COUNT]; 714 715 ddf_msg(LVL_NOTE, "current_descr=%p, prev_descr=%p", descr, prev); 716 717 descr->control = CONTROL_OWN | CONTROL_FS | CONTROL_LS; 718 descr->control |= size & 0xffff; 719 descr->vlan = 0; 720 descr->buf_low = buff_phys & 0xffffffff; 721 descr->buf_high = (buff_phys >> 32) & 0xffffffff; 722 rtl8169->tx_head = (head + 1) % TX_BUFFERS_COUNT; 723 724 /* Lift EOR flag from previous descriptor */ 725 prev->control &= ~CONTROL_EOR; 726 727 write_barrier(); 728 729 /* Notify NIC of pending packets */ 730 pio_write_8(rtl8169->regs + TPPOLL, TPPOLL_NPQ); 731 732 fibril_mutex_unlock(&rtl8169->tx_lock); 620 733 } 621 734
Note:
See TracChangeset
for help on using the changeset viewer.