lkml.org 
[lkml]   [2008]   [Nov]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 21/49] r8169: get ethtool settings through the generic mii helper
    2.6.27-stable review patch.  If anyone has any objections, please let us know.

    ------------------

    From: Francois Romieu <romieu@fr.zoreil.com>

    Upstream as ccdffb9a88b2907b159538d7bfd6256621db4f84 (post 2.6.27).

    It avoids to report unsupported link capabilities with
    the fast-ethernet only 8101/8102.

    Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
    Tested-by: Martin Capitanio <martin@capitanio.org>
    Fixed-by: Ivan Vecera <ivecera@redhat.com>
    Cc: Edward Hsu <edward_hsu@realtek.com.tw>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

    ---
    drivers/net/r8169.c | 97 ++++++++++++++++++++++++----------------------------
    1 file changed, 45 insertions(+), 52 deletions(-)

    --- a/drivers/net/r8169.c
    +++ b/drivers/net/r8169.c
    @@ -370,8 +370,9 @@ struct ring_info {
    };

    enum features {
    - RTL_FEATURE_WOL = (1 << 0),
    - RTL_FEATURE_MSI = (1 << 1),
    + RTL_FEATURE_WOL = (1 << 0),
    + RTL_FEATURE_MSI = (1 << 1),
    + RTL_FEATURE_GMII = (1 << 2),
    };

    struct rtl8169_private {
    @@ -406,13 +407,15 @@ struct rtl8169_private {
    struct vlan_group *vlgrp;
    #endif
    int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex);
    - void (*get_settings)(struct net_device *, struct ethtool_cmd *);
    + int (*get_settings)(struct net_device *, struct ethtool_cmd *);
    void (*phy_reset_enable)(void __iomem *);
    void (*hw_start)(struct net_device *);
    unsigned int (*phy_reset_pending)(void __iomem *);
    unsigned int (*link_ok)(void __iomem *);
    struct delayed_work task;
    unsigned features;
    +
    + struct mii_if_info mii;
    };

    MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
    @@ -482,6 +485,23 @@ static int mdio_read(void __iomem *ioadd
    return value;
    }

    +static void rtl_mdio_write(struct net_device *dev, int phy_id, int location,
    + int val)
    +{
    + struct rtl8169_private *tp = netdev_priv(dev);
    + void __iomem *ioaddr = tp->mmio_addr;
    +
    + mdio_write(ioaddr, location, val);
    +}
    +
    +static int rtl_mdio_read(struct net_device *dev, int phy_id, int location)
    +{
    + struct rtl8169_private *tp = netdev_priv(dev);
    + void __iomem *ioaddr = tp->mmio_addr;
    +
    + return mdio_read(ioaddr, location);
    +}
    +
    static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr)
    {
    RTL_W16(IntrMask, 0x0000);
    @@ -850,7 +870,7 @@ static int rtl8169_rx_vlan_skb(struct rt

    #endif

    -static void rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
    +static int rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
    {
    struct rtl8169_private *tp = netdev_priv(dev);
    void __iomem *ioaddr = tp->mmio_addr;
    @@ -867,65 +887,29 @@ static void rtl8169_gset_tbi(struct net_

    cmd->speed = SPEED_1000;
    cmd->duplex = DUPLEX_FULL; /* Always set */
    +
    + return 0;
    }

    -static void rtl8169_gset_xmii(struct net_device *dev, struct ethtool_cmd *cmd)
    +static int rtl8169_gset_xmii(struct net_device *dev, struct ethtool_cmd *cmd)
    {
    struct rtl8169_private *tp = netdev_priv(dev);
    - void __iomem *ioaddr = tp->mmio_addr;
    - u8 status;
    -
    - cmd->supported = SUPPORTED_10baseT_Half |
    - SUPPORTED_10baseT_Full |
    - SUPPORTED_100baseT_Half |
    - SUPPORTED_100baseT_Full |
    - SUPPORTED_1000baseT_Full |
    - SUPPORTED_Autoneg |
    - SUPPORTED_TP;
    -
    - cmd->autoneg = 1;
    - cmd->advertising = ADVERTISED_TP | ADVERTISED_Autoneg;
    -
    - if (tp->phy_auto_nego_reg & ADVERTISE_10HALF)
    - cmd->advertising |= ADVERTISED_10baseT_Half;
    - if (tp->phy_auto_nego_reg & ADVERTISE_10FULL)
    - cmd->advertising |= ADVERTISED_10baseT_Full;
    - if (tp->phy_auto_nego_reg & ADVERTISE_100HALF)
    - cmd->advertising |= ADVERTISED_100baseT_Half;
    - if (tp->phy_auto_nego_reg & ADVERTISE_100FULL)
    - cmd->advertising |= ADVERTISED_100baseT_Full;
    - if (tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL)
    - cmd->advertising |= ADVERTISED_1000baseT_Full;
    -
    - status = RTL_R8(PHYstatus);
    -
    - if (status & _1000bpsF)
    - cmd->speed = SPEED_1000;
    - else if (status & _100bps)
    - cmd->speed = SPEED_100;
    - else if (status & _10bps)
    - cmd->speed = SPEED_10;
    -
    - if (status & TxFlowCtrl)
    - cmd->advertising |= ADVERTISED_Asym_Pause;
    - if (status & RxFlowCtrl)
    - cmd->advertising |= ADVERTISED_Pause;

    - cmd->duplex = ((status & _1000bpsF) || (status & FullDup)) ?
    - DUPLEX_FULL : DUPLEX_HALF;
    + return mii_ethtool_gset(&tp->mii, cmd);
    }

    static int rtl8169_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
    {
    struct rtl8169_private *tp = netdev_priv(dev);
    unsigned long flags;
    + int rc;

    spin_lock_irqsave(&tp->lock, flags);

    - tp->get_settings(dev, cmd);
    + rc = tp->get_settings(dev, cmd);

    spin_unlock_irqrestore(&tp->lock, flags);
    - return 0;
    + return rc;
    }

    static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs,
    @@ -1513,7 +1497,7 @@ static const struct rtl_cfg_info {
    unsigned int align;
    u16 intr_event;
    u16 napi_event;
    - unsigned msi;
    + unsigned features;
    } rtl_cfg_infos [] = {
    [RTL_CFG_0] = {
    .hw_start = rtl_hw_start_8169,
    @@ -1522,7 +1506,7 @@ static const struct rtl_cfg_info {
    .intr_event = SYSErr | LinkChg | RxOverflow |
    RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
    .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
    - .msi = 0
    + .features = RTL_FEATURE_GMII
    },
    [RTL_CFG_1] = {
    .hw_start = rtl_hw_start_8168,
    @@ -1531,7 +1515,7 @@ static const struct rtl_cfg_info {
    .intr_event = SYSErr | LinkChg | RxOverflow |
    TxErr | TxOK | RxOK | RxErr,
    .napi_event = TxErr | TxOK | RxOK | RxOverflow,
    - .msi = RTL_FEATURE_MSI
    + .features = RTL_FEATURE_GMII | RTL_FEATURE_MSI
    },
    [RTL_CFG_2] = {
    .hw_start = rtl_hw_start_8101,
    @@ -1540,7 +1524,7 @@ static const struct rtl_cfg_info {
    .intr_event = SYSErr | LinkChg | RxOverflow | PCSTimeout |
    RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
    .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
    - .msi = RTL_FEATURE_MSI
    + .features = RTL_FEATURE_MSI
    }
    };

    @@ -1552,7 +1536,7 @@ static unsigned rtl_try_msi(struct pci_d
    u8 cfg2;

    cfg2 = RTL_R8(Config2) & ~MSIEnable;
    - if (cfg->msi) {
    + if (cfg->features & RTL_FEATURE_MSI) {
    if (pci_enable_msi(pdev)) {
    dev_info(&pdev->dev, "no MSI. Back to INTx.\n");
    } else {
    @@ -1578,6 +1562,7 @@ rtl8169_init_one(struct pci_dev *pdev, c
    const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data;
    const unsigned int region = cfg->region;
    struct rtl8169_private *tp;
    + struct mii_if_info *mii;
    struct net_device *dev;
    void __iomem *ioaddr;
    unsigned int i;
    @@ -1602,6 +1587,14 @@ rtl8169_init_one(struct pci_dev *pdev, c
    tp->pci_dev = pdev;
    tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT);

    + mii = &tp->mii;
    + mii->dev = dev;
    + mii->mdio_read = rtl_mdio_read;
    + mii->mdio_write = rtl_mdio_write;
    + mii->phy_id_mask = 0x1f;
    + mii->reg_num_mask = 0x1f;
    + mii->supports_gmii = !!(cfg->features & RTL_FEATURE_GMII);
    +
    /* enable device (incl. PCI PM wakeup and hotplug setup) */
    rc = pci_enable_device(pdev);
    if (rc < 0) {
    --


    \
     
     \ /
      Last update: 2008-11-12 01:37    [W:4.607 / U:0.860 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site