Changeset c62a8275 in mainline for uspace/drv/nic/rtl8169/driver.c


Ignore:
Timestamp:
2014-09-01T11:17:23Z (10 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a4666a9
Parents:
f93ba6d (diff), 320bd52 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge from lp:~nufcia/helenos/rtl8169.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/nic/rtl8169/driver.c

    rf93ba6d rc62a8275  
    2727 */
    2828
    29 #define _DDF_DATA_IMPLANT
    30 
    3129#include <assert.h>
    3230#include <errno.h>
     
    330328}
    331329
     330static void rtl8169_dev_cleanup(ddf_dev_t *dev)
     331{
     332        assert(dev);
     333
     334        if (ddf_dev_data_get(dev))
     335                nic_unbind_and_destroy(dev);
     336}
     337
    332338static int rtl8169_dev_initialize(ddf_dev_t *dev)
    333339{
     
    351357failed:
    352358        ddf_msg(LVL_ERROR, "The device initialization failed");
    353 //      rtl8139_dev_cleanup(dev);
     359        rtl8169_dev_cleanup(dev);
    354360        return ret;
    355361
     
    439445        nic_set_ddf_fun(nic_data, fun);
    440446        ddf_fun_set_ops(fun, &rtl8169_dev_ops);
    441 //      ddf_fun_data_implant(fun, nic_data);
    442447
    443448        rc = ddf_fun_bind(fun);
     
    467472err_pio:
    468473err_destroy:
    469         //rtl8169_dev_cleanup(dev);
     474        rtl8169_dev_cleanup(dev);
    470475        return rc;
    471476
     
    733738        /* Configure Receive Control Register */
    734739        uint32_t rcr = pio_read_32(rtl8169->regs + RCR);
    735         rcr |= RCR_ACCEPT_ALL_PHYS | RCR_ACCEPT_PHYS_MATCH \
    736             | RCR_ACCEPT_BROADCAST | RCR_ACCEPT_ERROR \
    737             | RCR_ACCEPT_RUNT;
     740        rtl8169->rcr_ucast = RCR_ACCEPT_PHYS_MATCH;
     741        rcr |= RCR_ACCEPT_PHYS_MATCH | RCR_ACCEPT_ERROR | RCR_ACCEPT_RUNT;
    738742        pio_write_32(rtl8169->regs + RCR, rcr);
    739743        pio_write_16(rtl8169->regs + RMS, BUFFER_SIZE);
    740 
    741         ddf_msg(LVL_NOTE, "RCR: 0x%08x", pio_read_32(rtl8169->regs + RCR));
    742 
    743744
    744745        pio_write_16(rtl8169->regs + IMR, 0xffff);
     
    793794}
    794795
     796/** Notify NIC framework about HW filtering state when promisc mode was disabled
     797 *
     798 *  @param nic_data     The NIC data
     799 *  @param mcast_mode   Current multicast mode
     800 *  @param was_promisc  Sign if the promiscuous mode was active before disabling
     801 */
     802inline static void rtl8169_rcx_promics_rem(nic_t *nic_data,
     803    nic_multicast_mode_t mcast_mode, uint8_t was_promisc)
     804{
     805        assert(nic_data);
     806
     807        if (was_promisc != 0) {
     808                if (mcast_mode == NIC_MULTICAST_LIST)
     809                        nic_report_hw_filtering(nic_data, 1, 0, -1);
     810                else
     811                        nic_report_hw_filtering(nic_data, 1, 1, -1);
     812        } else {
     813                nic_report_hw_filtering(nic_data, 1, -1, -1);
     814        }
     815}
     816
    795817static int rtl8169_unicast_set(nic_t *nic_data, nic_unicast_mode_t mode,
    796818    const nic_address_t *addr, size_t addr_count)
    797819{
     820        rtl8169_t *rtl8169 = nic_get_specific(nic_data);
     821        uint32_t rcr = pio_read_32(rtl8169->regs + RCR);
     822        uint8_t was_promisc = rcr & RCR_ACCEPT_ALL_PHYS;
     823        nic_multicast_mode_t mcast_mode;
     824
     825        nic_query_multicast(nic_data, &mcast_mode, 0, NULL, NULL);
     826
     827        ddf_msg(LVL_DEBUG, "Unicast RX filter mode: %d", mode);
     828
     829
     830        switch (mode) {
     831        case NIC_UNICAST_BLOCKED:
     832                rtl8169->rcr_ucast = 0;
     833                rtl8169_rcx_promics_rem(nic_data, mcast_mode, was_promisc);
     834                break;
     835        case NIC_UNICAST_DEFAULT:
     836                rtl8169->rcr_ucast = RCR_ACCEPT_PHYS_MATCH;
     837                rtl8169_rcx_promics_rem(nic_data, mcast_mode, was_promisc);
     838                break;
     839        case NIC_UNICAST_LIST:
     840                rtl8169->rcr_ucast = RCR_ACCEPT_PHYS_MATCH | RCR_ACCEPT_ALL_PHYS;
     841
     842                if (mcast_mode == NIC_MULTICAST_PROMISC)
     843                        nic_report_hw_filtering(nic_data, 0, 1, -1);
     844                else
     845                        nic_report_hw_filtering(nic_data, 0, 0, -1);
     846                break;
     847        case NIC_UNICAST_PROMISC:
     848                rtl8169->rcr_ucast = RCR_ACCEPT_PHYS_MATCH | RCR_ACCEPT_ALL_PHYS;
     849
     850                if (mcast_mode == NIC_MULTICAST_PROMISC)
     851                        nic_report_hw_filtering(nic_data, 1, 1, -1);
     852                else
     853                        nic_report_hw_filtering(nic_data, 1, 0, -1);
     854                break;
     855        default:
     856                return ENOTSUP;
     857        }
     858
     859        fibril_mutex_lock(&rtl8169->rx_lock);
     860
     861        rcr &= ~(RCR_ACCEPT_PHYS_MATCH | RCR_ACCEPT_ALL_PHYS);
     862        pio_write_32(rtl8169->regs + RCR, rcr | rtl8169->rcr_ucast | rtl8169->rcr_mcast);
     863        ddf_msg(LVL_DEBUG, "new RCR value: 0x%08x", rcr | rtl8169->rcr_ucast | rtl8169->rcr_mcast);
     864
     865        fibril_mutex_unlock(&rtl8169->rx_lock);
    798866        return EOK;
    799867}
     
    802870    const nic_address_t *addr, size_t addr_count)
    803871{
     872        rtl8169_t *rtl8169 = nic_get_specific(nic_data);
     873        uint32_t rcr = pio_read_32(rtl8169->regs + RCR);
     874        uint64_t mask;
     875
     876        ddf_msg(LVL_DEBUG, "Multicast RX filter mode: %d", mode);
     877
     878        switch (mode) {
     879        case NIC_MULTICAST_BLOCKED:
     880                rtl8169->rcr_mcast = 0;
     881                if ((rtl8169->rcr_ucast & RCR_ACCEPT_ALL_PHYS) != 0)
     882                        nic_report_hw_filtering(nic_data, -1, 0, -1);
     883                else
     884                        nic_report_hw_filtering(nic_data, -1, 1, -1);
     885                break;
     886        case NIC_MULTICAST_LIST:
     887                mask = nic_mcast_hash(addr, addr_count);
     888                pio_write_32(rtl8169->regs + MAR0, (uint32_t)mask);
     889                pio_write_32(rtl8169->regs + MAR0 + 4, (uint32_t)(mask >> 32));
     890                rtl8169->rcr_mcast = RCR_ACCEPT_MULTICAST;
     891                nic_report_hw_filtering(nic_data, -1, 0, -1);
     892                break;
     893        case NIC_MULTICAST_PROMISC:
     894                pio_write_32(rtl8169->regs + MAR0, 0xffffffffULL);
     895                pio_write_32(rtl8169->regs + MAR0 + 4, (uint32_t)(0xffffffffULL >> 32));
     896                rtl8169->rcr_mcast = RCR_ACCEPT_MULTICAST;
     897                nic_report_hw_filtering(nic_data, -1, 1, -1);
     898                break;
     899        default:
     900                return ENOTSUP;
     901        }
     902
     903        fibril_mutex_lock(&rtl8169->rx_lock);
     904
     905        rcr &= ~(RCR_ACCEPT_PHYS_MATCH | RCR_ACCEPT_ALL_PHYS);
     906        pio_write_32(rtl8169->regs + RCR, rcr | rtl8169->rcr_ucast | rtl8169->rcr_mcast);
     907        ddf_msg(LVL_DEBUG, "new RCR value: 0x%08x", rcr | rtl8169->rcr_ucast | rtl8169->rcr_mcast);
     908
     909        fibril_mutex_unlock(&rtl8169->rx_lock);
    804910        return EOK;
    805911}
     
    807913static int rtl8169_broadcast_set(nic_t *nic_data, nic_broadcast_mode_t mode)
    808914{
     915        rtl8169_t *rtl8169 = nic_get_specific(nic_data);
     916       
     917        /* Configure Receive Control Register */
     918        uint32_t rcr = pio_read_32(rtl8169->regs + RCR);
     919
     920        ddf_msg(LVL_DEBUG, "Broadcast RX filter mode: %d", mode);
     921
     922        switch (mode) {
     923        case NIC_BROADCAST_BLOCKED:
     924                rcr &= RCR_ACCEPT_BROADCAST;
     925                break;
     926        case NIC_BROADCAST_ACCEPTED:
     927                rcr |= RCR_ACCEPT_BROADCAST;
     928                break;
     929        default:
     930                return ENOTSUP;
     931        }
     932
     933        pio_write_32(rtl8169->regs + RCR, rcr);
     934        ddf_msg(LVL_DEBUG," new RCR value: 0x%08x", rcr);
     935
    809936        return EOK;
    810937}
     
    816943        rtl8169_t *rtl8169 = nic_get_specific(nic_data);
    817944        rtl8169_descr_t *descr;
    818 
    819         ddf_msg(LVL_NOTE, "rtl8169_transmit_done()");
     945        int sent = 0;
     946
     947        ddf_msg(LVL_DEBUG, "rtl8169_transmit_done()");
    820948
    821949        fibril_mutex_lock(&rtl8169->tx_lock);
     
    828956                descr->control &= (~CONTROL_OWN);
    829957                write_barrier();
    830                 ddf_msg(LVL_NOTE, "TX status for descr %d: 0x%08x", tail, descr->control);
     958                ddf_msg(LVL_DEBUG, "TX status for descr %d: 0x%08x", tail, descr->control);
    831959       
    832960                tail = (tail + 1) % TX_BUFFERS_COUNT;
    833         }
     961                sent++;
     962        }
     963
     964        if (sent != 0)
     965                nic_set_tx_busy(nic_data, 0);
    834966
    835967        rtl8169->tx_tail = tail;
     
    849981        int frame_size;
    850982
    851         ddf_msg(LVL_NOTE, "rtl8169_receive_done()");
     983        ddf_msg(LVL_DEBUG, "rtl8169_receive_done()");
    852984
    853985        fibril_mutex_lock(&rtl8169->rx_lock);
     
    862994
    863995                if (descr->control & RXSTATUS_RES) {
    864                         ddf_msg(LVL_NOTE, "error at slot %d: 0x%08x\n", tail, descr->control);
     996                        ddf_msg(LVL_WARN, "error at slot %d: 0x%08x\n", tail, descr->control);
    865997                        tail = (tail + 1) % RX_BUFFERS_COUNT;
    866998                        continue;
     
    8711003               
    8721004                if (descr->control & CONTROL_LS) {
    873 
    874                         ddf_msg(LVL_NOTE, "received message at slot %d, control 0x%08x", tail, descr->control);
     1005                        ddf_msg(LVL_DEBUG, "received message at slot %d, control 0x%08x", tail, descr->control);
    8751006
    8761007                        if (fsidx != tail)
     
    9071038        rtl8169_t *rtl8169 = nic_get_specific(nic_data);
    9081039
    909         ddf_msg(LVL_NOTE, "rtl8169_irq_handler(): isr=0x%04x", isr);
     1040        ddf_msg(LVL_DEBUG, "rtl8169_irq_handler(): isr=0x%04x", isr);
    9101041        pio_write_16(rtl8169->regs + IMR, 0xffff);
    9111042
     
    9631094        fibril_mutex_lock(&rtl8169->tx_lock);
    9641095
    965         ddf_msg(LVL_NOTE, "send_frame: size: %zu, tx_head=%d tx_tail=%d",
     1096        ddf_msg(LVL_DEBUG, "send_frame: size: %zu, tx_head=%d tx_tail=%d",
    9661097            size, rtl8169->tx_head, rtl8169->tx_tail);
    9671098
     
    9861117        prev = &rtl8169->tx_ring[(head - 1) % TX_BUFFERS_COUNT];
    9871118
    988         ddf_msg(LVL_NOTE, "current_descr=%p, prev_descr=%p", descr, prev);
     1119        ddf_msg(LVL_DEBUG, "current_descr=%p, prev_descr=%p", descr, prev);
    9891120
    9901121        descr->control = CONTROL_OWN | CONTROL_FS | CONTROL_LS;
Note: See TracChangeset for help on using the changeset viewer.