Fork us on GitHub Follow us on Facebook Follow us on Twitter

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


Ignore:
Timestamp:
2014-06-30T21:08:06Z (7 years ago)
Author:
Agnieszka Tabaka <nufcia@…>
Branches:
master
Children:
ca652eb
Parents:
91e057c
Message:

Add functions to access RTL8169's PHY (rtl8169_mii_read and rtl8169_mii_write)
and fill most of existing stubs of nic_iface_t functions.

File:
1 edited

Legend:

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

    r91e057c r727e639  
    9292static int rtl8169_broadcast_set(nic_t *nic_data, nic_broadcast_mode_t mode);
    9393
     94static uint16_t rtl8169_mii_read(rtl8169_t *rtl8169, uint8_t addr);
     95static void rtl8169_mii_write(rtl8169_t *rtl8169, uint8_t addr, uint16_t value);
    9496static void rtl8169_rx_ring_refill(rtl8169_t *rtl8169, unsigned int first,
    9597    unsigned int last);
     
    494496    nic_channel_mode_t *duplex, nic_role_t *role)
    495497{
     498        rtl8169_t *rtl8169 = nic_get_specific(nic_get_from_ddf_fun(fun));
     499        uint8_t phystatus = pio_read_8(rtl8169->regs + PHYSTATUS);
     500
     501        *duplex = phystatus & PHYSTATUS_FDX
     502            ? NIC_CM_FULL_DUPLEX : NIC_CM_HALF_DUPLEX;
     503
     504        if (phystatus & PHYSTATUS_10M)
     505                *speed = 10;
     506
     507        if (phystatus & PHYSTATUS_100M)
     508                *speed = 100;
     509
     510        if (phystatus & PHYSTATUS_1000M)
     511                *speed = 1000;
     512
     513        *role = NIC_ROLE_UNKNOWN;
    496514        return EOK;
    497515}
     
    500518    nic_channel_mode_t duplex, nic_role_t role)
    501519{
     520        rtl8169_t *rtl8169 = nic_get_specific(nic_get_from_ddf_fun(fun));
     521        uint16_t bmcr;
     522
     523        if (speed != 10 && speed != 100 && speed != 1000)
     524                return EINVAL;
     525
     526        if (duplex != NIC_CM_HALF_DUPLEX && duplex != NIC_CM_FULL_DUPLEX)
     527                return EINVAL;
     528
     529        bmcr = rtl8169_mii_read(rtl8169, MII_BMCR);
     530        bmcr &= ~(BMCR_DUPLEX | BMCR_SPD_100 | BMCR_SPD_1000);
     531       
     532        if (duplex == NIC_CM_FULL_DUPLEX)
     533                bmcr |= BMCR_DUPLEX;
     534
     535        if (speed == 100)
     536                bmcr |= BMCR_SPD_100;
     537
     538        if (speed == 1000)
     539                bmcr |= BMCR_SPD_1000;
     540
     541        rtl8169_mii_write(rtl8169, MII_BMCR, bmcr);
    502542        return EOK;
    503543}
     
    517557static int rtl8169_autoneg_enable(ddf_fun_t *fun, uint32_t advertisement)
    518558{
     559        rtl8169_t *rtl8169 = nic_get_specific(nic_get_from_ddf_fun(fun));
     560        uint16_t bmcr = rtl8169_mii_read(rtl8169, MII_BMCR);
     561        uint16_t anar = ANAR_SELECTOR;
     562
     563        if (advertisement & ETH_AUTONEG_10BASE_T_FULL)
     564                anar |= ANAR_10_FD;
     565        if (advertisement & ETH_AUTONEG_10BASE_T_HALF)
     566                anar |= ANAR_10_HD;
     567        if (advertisement & ETH_AUTONEG_100BASE_TX_FULL)
     568                anar |= ANAR_100TX_FD;
     569        if (advertisement & ETH_AUTONEG_100BASE_TX_HALF)
     570                anar |= ANAR_100TX_HD;
     571        if (advertisement & ETH_AUTONEG_PAUSE_SYMETRIC)
     572                anar |= ANAR_PAUSE;
     573
     574        bmcr |= BMCR_AN_ENABLE;
     575        rtl8169_mii_write(rtl8169, MII_BMCR, bmcr);
     576        rtl8169_mii_write(rtl8169, MII_ANAR, anar);
     577
    519578        return EOK;
    520579}
     
    522581static int rtl8169_autoneg_disable(ddf_fun_t *fun)
    523582{
     583        rtl8169_t *rtl8169 = nic_get_specific(nic_get_from_ddf_fun(fun));
     584        uint16_t bmcr = rtl8169_mii_read(rtl8169, MII_BMCR);
     585
     586        bmcr &= ~BMCR_AN_ENABLE;
     587        rtl8169_mii_write(rtl8169, MII_BMCR, bmcr);
     588
    524589        return EOK;
    525590}
     
    910975}
    911976
     977static uint16_t rtl8169_mii_read(rtl8169_t *rtl8169, uint8_t addr)
     978{
     979        uint32_t phyar;
     980
     981        phyar = PHYAR_RW_READ
     982            | ((addr & PHYAR_ADDR_MASK) << PHYAR_ADDR_SHIFT);
     983
     984        pio_write_32(rtl8169->regs + PHYAR, phyar);
     985
     986        do {
     987                phyar = pio_read_32(rtl8169->regs + PHYAR);
     988                usleep(20);
     989        } while ((phyar & PHYAR_RW_WRITE) == 0);
     990
     991        return phyar & PHYAR_DATA_MASK;
     992}
     993
     994static void rtl8169_mii_write(rtl8169_t *rtl8169, uint8_t addr, uint16_t value)
     995{
     996        uint32_t phyar;
     997
     998        phyar = PHYAR_RW_WRITE
     999            | ((addr & PHYAR_ADDR_MASK) << PHYAR_ADDR_SHIFT)
     1000            | (value & PHYAR_DATA_MASK);
     1001
     1002        pio_write_32(rtl8169->regs + PHYAR, phyar);
     1003
     1004        do {
     1005                phyar = pio_read_32(rtl8169->regs + PHYAR);
     1006                usleep(20);
     1007        } while ((phyar & PHYAR_RW_WRITE) != 0);
     1008
     1009        usleep(20);
     1010}
     1011
    9121012/** Main function of RTL8169 driver
    9131013*
Note: See TracChangeset for help on using the changeset viewer.