Changeset be971233 in mainline
- Timestamp:
- 2014-06-09T20:44:00Z (11 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- e37d2f81
- Parents:
- 59b3095
- Location:
- uspace/drv/nic/rtl8169
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/nic/rtl8169/defs.h
r59b3095 rbe971233 282 282 }; 283 283 284 enum rtl8169_descr_rxstatus { 285 RXSTATUS_MAR = (1 << 27), 286 RXSTATUS_PAM = (1 << 26), 287 RXSTATUS_BAR = (1 << 25), 288 RXSTATUS_BOVF = (1 << 24), 289 RXSTATUS_FOVF = (1 << 23), 290 RXSTATUS_RWT = (1 << 22), 291 RXSTATUS_RES = (1 << 21), 292 RXSTATUS_RUNT = (1 << 20), 293 RXSTATUS_CRC = (1 << 19), 294 RXSTATUS_PID1 = (1 << 18), 295 RXSTATUS_PID0 = (1 << 17), 296 RXSTATUS_IPF = (1 << 16), 297 RXSTATUS_UDPF = (1 << 15), 298 RXSTATUS_TCPF = (1 << 14) 299 }; 300 284 301 typedef struct rtl8169_descr { 285 302 uint32_t control; -
uspace/drv/nic/rtl8169/driver.c
r59b3095 rbe971233 93 93 static int rtl8169_broadcast_set(nic_t *nic_data, nic_broadcast_mode_t mode); 94 94 95 static void rtl8169_rx_ring_refill(rtl8169_t *rtl8169, unsigned int first, 96 unsigned int last); 95 97 96 98 /** Network interface options for RTL8169 card driver */ … … 243 245 return rc; 244 246 247 memset(rtl8169->tx_ring, 0, TX_RING_SIZE); 248 245 249 /* Allocate RX ring */ 246 250 rc = dmamem_map_anonymous(RX_RING_SIZE, DMAMEM_4GiB, … … 250 254 if (rc != EOK) 251 255 return rc; 256 257 memset(rtl8169->rx_ring, 0, RX_RING_SIZE); 252 258 253 259 /* Allocate TX buffers */ … … 514 520 } 515 521 522 static void rtl8169_rx_ring_refill(rtl8169_t *rtl8169, unsigned int first, 523 unsigned int last) 524 { 525 rtl8169_descr_t *descr; 526 uintptr_t buff_phys; 527 unsigned int i = first; 528 529 for (;;) { 530 descr = &rtl8169->rx_ring[i]; 531 buff_phys = rtl8169->rx_buff_phys + (BUFFER_SIZE * i); 532 descr->control = BUFFER_SIZE | CONTROL_OWN; 533 descr->buf_low = buff_phys & 0xffffffff; 534 descr->buf_high = (buff_phys >> 32) & 0xffffffff; 535 536 if (i == RX_BUFFERS_COUNT - 1) 537 descr->control |= CONTROL_EOR; 538 539 if (i == last) 540 break; 541 542 i = (i + 1) % RX_BUFFERS_COUNT; 543 } 544 } 545 516 546 static int rtl8169_on_activated(nic_t *nic_data) 517 547 { … … 526 556 /* Allocate buffers */ 527 557 rtl8169_allocate_buffers(rtl8169); 558 559 /* Initialize RX ring */ 560 rtl8169_rx_ring_refill(rtl8169, 0, RX_BUFFERS_COUNT - 1); 528 561 529 562 /* Write address of descriptor as start of TX ring */ … … 534 567 rtl8169->tx_ring[15].control = CONTROL_EOR; 535 568 569 /* Write RX ring address */ 570 pio_write_32(rtl8169->regs + RDSAR, rtl8169->rx_ring_phys & 0xffffffff); 571 pio_write_32(rtl8169->regs + RDSAR + 4, (rtl8169->rx_ring_phys >> 32) & 0xffffffff); 572 rtl8169->rx_head = 0; 573 rtl8169->rx_tail = 0; 574 575 /* Clear pending interrupts */ 576 pio_write_16(rtl8169->regs + ISR, 0xffff); 577 536 578 /* Enable TX and RX */ 537 579 uint8_t cr = pio_read_8(rtl8169->regs + CR); 538 580 cr |= CR_TE | CR_RE; 539 581 pio_write_8(rtl8169->regs + CR, cr); 582 pio_write_32(rtl8169->regs + MAR0, 0xffffffff); 583 pio_write_32(rtl8169->regs + MAR0 + 4, 0xffffffff); 584 585 /* Configure Receive Control Register */ 586 pio_write_8(rtl8169->regs + 0x50, 0xc0); 587 uint32_t rcr = pio_read_32(rtl8169->regs + RCR); 588 rcr |= RCR_ACCEPT_ALL_PHYS | RCR_ACCEPT_PHYS_MATCH \ 589 | RCR_ACCEPT_BROADCAST | RCR_ACCEPT_ERROR \ 590 | RCR_ACCEPT_RUNT; 591 pio_write_32(rtl8169->regs + RCR, rcr); 592 pio_write_16(rtl8169->regs + RMS, BUFFER_SIZE); 593 pio_write_8(rtl8169->regs + 0x50, 0x00); 594 595 ddf_msg(LVL_NOTE, "RCR: 0x%08x", pio_read_32(rtl8169->regs + RCR)); 596 540 597 541 598 pio_write_16(rtl8169->regs + IMR, 0xffff); … … 623 680 while (tail != head) { 624 681 descr = &rtl8169->tx_ring[tail]; 682 descr->control |= CONTROL_OWN; 683 ddf_msg(LVL_NOTE, "TX status for descr %d: 0x%08x", tail, descr->control); 684 625 685 tail = (tail + 1) % TX_BUFFERS_COUNT; 626 627 ddf_msg(LVL_NOTE, "TX status for descr %d: 0x%08x", tail, descr->control);628 686 } 629 687 … … 631 689 632 690 fibril_mutex_unlock(&rtl8169->tx_lock); 691 } 692 693 static void rtl8169_receive_done(ddf_dev_t *dev) 694 { 695 nic_t *nic_data = nic_get_from_ddf_dev(dev); 696 rtl8169_t *rtl8169 = nic_get_specific(nic_data); 697 rtl8169_descr_t *descr; 698 nic_frame_list_t *frames = nic_alloc_frame_list(); 699 nic_frame_t *frame; 700 void *buffer; 701 unsigned int tail, fsidx = 0; 702 int frame_size; 703 704 ddf_msg(LVL_NOTE, "rtl8169_receive_done()"); 705 706 fibril_mutex_lock(&rtl8169->rx_lock); 707 708 tail = rtl8169->rx_tail; 709 710 for (;;) { 711 descr = &rtl8169->rx_ring[tail]; 712 713 if (descr->control & CONTROL_OWN) 714 break; 715 716 if (descr->control & RXSTATUS_RES) { 717 ddf_msg(LVL_NOTE, "error at slot %d: 0x%08x\n", tail, descr->control); 718 tail = (tail + 1) % RX_BUFFERS_COUNT; 719 continue; 720 } 721 722 if (descr->control & CONTROL_FS) 723 fsidx = tail; 724 725 if (descr->control & CONTROL_LS) { 726 727 ddf_msg(LVL_NOTE, "received message at slot %d, control 0x%08x", tail, descr->control); 728 729 if (fsidx != tail) 730 ddf_msg(LVL_WARN, "single frame spanning multiple descriptors"); 731 732 frame_size = descr->control & 0x1fff; 733 buffer = rtl8169->rx_buff + (BUFFER_SIZE * tail); 734 frame = nic_alloc_frame(nic_data, frame_size); 735 memcpy(frame->data, buffer, frame_size); 736 nic_frame_list_append(frames, frame); 737 } 738 739 tail = (tail + 1) % RX_BUFFERS_COUNT; 740 } 741 742 rtl8169_rx_ring_refill(rtl8169, rtl8169->rx_tail, tail); 743 744 rtl8169->rx_tail = tail; 745 746 fibril_mutex_unlock(&rtl8169->rx_lock); 747 748 nic_received_frame_list(nic_data, frames); 749 633 750 } 634 751 … … 643 760 rtl8169_t *rtl8169 = nic_get_specific(nic_data); 644 761 645 //ddf_msg(LVL_NOTE, "rtl8169_irq_handler(): isr=0x%04x", isr);762 ddf_msg(LVL_NOTE, "rtl8169_irq_handler(): isr=0x%04x", isr); 646 763 647 764 /* Packet underrun or link change */ … … 649 766 rtl8169_link_change(dev); 650 767 651 /* Frame(s) successfully transmitted */ 652 if (isr & INT_TOK) 653 rtl8169_transmit_done(dev); 654 655 /* Transmit error */ 656 if (isr & INT_TER) 768 /* Transmit notification */ 769 if (isr & (INT_TER | INT_TOK | INT_TDU)) 657 770 rtl8169_transmit_done(dev); 658 771 … … 660 773 ddf_msg(LVL_ERROR, "System error interrupt"); 661 774 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"); 775 if (isr & (INT_RER | INT_ROK)) 776 rtl8169_receive_done(dev); 670 777 671 778 pio_write_16(rtl8169->regs + ISR, 0xffff); … … 690 797 691 798 ddf_msg(LVL_NOTE, "send_frame()"); 799 ddf_msg(LVL_NOTE, "size: %ld", size); 692 800 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 801 ddf_msg(LVL_NOTE, "tx_head=%d tx_tail=%d", rtl8169->tx_head, rtl8169->tx_tail); 695 802 … … 697 804 tail = rtl8169->tx_tail; 698 805 699 if (( tail + 1) % TX_BUFFERS_COUNT == head) {806 if ((head + 1) % TX_BUFFERS_COUNT == tail) { 700 807 /* Queue is full */ 808 ddf_msg(LVL_WARN, "TX queue full!"); 701 809 nic_set_tx_busy(nic_data, 1); 702 810 } … … 720 828 descr->buf_low = buff_phys & 0xffffffff; 721 829 descr->buf_high = (buff_phys >> 32) & 0xffffffff; 830 831 if (head == TX_BUFFERS_COUNT - 1) 832 descr->control |= CONTROL_EOR; 833 722 834 rtl8169->tx_head = (head + 1) % TX_BUFFERS_COUNT; 723 724 /* Lift EOR flag from previous descriptor */725 prev->control &= ~CONTROL_EOR;726 835 727 836 write_barrier();
Note:
See TracChangeset
for help on using the changeset viewer.