aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/r8169.c
diff options
context:
space:
mode:
authorFrancois Romieu <romieu@fr.zoreil.com>2008-07-26 08:26:06 -0400
committerFrancois Romieu <romieu@fr.zoreil.com>2008-08-17 09:53:04 -0400
commitccdffb9a88b2907b159538d7bfd6256621db4f84 (patch)
treee6d91e453d0db635089804b7bd023d18135abed5 /drivers/net/r8169.c
parentd6f8aa8586dabe605454f3c98a5c1a577c3e0cfb (diff)
r8169: get ethtool settings through the generic mii helper
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>
Diffstat (limited to 'drivers/net/r8169.c')
-rw-r--r--drivers/net/r8169.c99
1 files changed, 46 insertions, 53 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index a3e3895e5032..dac2677eeede 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -370,8 +370,9 @@ struct ring_info {
370}; 370};
371 371
372enum features { 372enum features {
373 RTL_FEATURE_WOL = (1 << 0), 373 RTL_FEATURE_WOL = (1 << 0),
374 RTL_FEATURE_MSI = (1 << 1), 374 RTL_FEATURE_MSI = (1 << 1),
375 RTL_FEATURE_GMII = (1 << 2),
375}; 376};
376 377
377struct rtl8169_private { 378struct rtl8169_private {
@@ -406,13 +407,15 @@ struct rtl8169_private {
406 struct vlan_group *vlgrp; 407 struct vlan_group *vlgrp;
407#endif 408#endif
408 int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex); 409 int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex);
409 void (*get_settings)(struct net_device *, struct ethtool_cmd *); 410 int (*get_settings)(struct net_device *, struct ethtool_cmd *);
410 void (*phy_reset_enable)(void __iomem *); 411 void (*phy_reset_enable)(void __iomem *);
411 void (*hw_start)(struct net_device *); 412 void (*hw_start)(struct net_device *);
412 unsigned int (*phy_reset_pending)(void __iomem *); 413 unsigned int (*phy_reset_pending)(void __iomem *);
413 unsigned int (*link_ok)(void __iomem *); 414 unsigned int (*link_ok)(void __iomem *);
414 struct delayed_work task; 415 struct delayed_work task;
415 unsigned features; 416 unsigned features;
417
418 struct mii_if_info mii;
416}; 419};
417 420
418MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); 421MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
@@ -482,6 +485,23 @@ static int mdio_read(void __iomem *ioaddr, int reg_addr)
482 return value; 485 return value;
483} 486}
484 487
488static void rtl_mdio_write(struct net_device *dev, int phy_id, int location,
489 int val)
490{
491 struct rtl8169_private *tp = netdev_priv(dev);
492 void __iomem *ioaddr = tp->mmio_addr;
493
494 mdio_write(ioaddr, location, val);
495}
496
497static int rtl_mdio_read(struct net_device *dev, int phy_id, int location)
498{
499 struct rtl8169_private *tp = netdev_priv(dev);
500 void __iomem *ioaddr = tp->mmio_addr;
501
502 return mdio_read(ioaddr, location);
503}
504
485static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr) 505static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr)
486{ 506{
487 RTL_W16(IntrMask, 0x0000); 507 RTL_W16(IntrMask, 0x0000);
@@ -850,7 +870,7 @@ static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc,
850 870
851#endif 871#endif
852 872
853static void rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd) 873static int rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
854{ 874{
855 struct rtl8169_private *tp = netdev_priv(dev); 875 struct rtl8169_private *tp = netdev_priv(dev);
856 void __iomem *ioaddr = tp->mmio_addr; 876 void __iomem *ioaddr = tp->mmio_addr;
@@ -867,65 +887,29 @@ static void rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
867 887
868 cmd->speed = SPEED_1000; 888 cmd->speed = SPEED_1000;
869 cmd->duplex = DUPLEX_FULL; /* Always set */ 889 cmd->duplex = DUPLEX_FULL; /* Always set */
890
891 return 0;
870} 892}
871 893
872static void rtl8169_gset_xmii(struct net_device *dev, struct ethtool_cmd *cmd) 894static int rtl8169_gset_xmii(struct net_device *dev, struct ethtool_cmd *cmd)
873{ 895{
874 struct rtl8169_private *tp = netdev_priv(dev); 896 struct rtl8169_private *tp = netdev_priv(dev);
875 void __iomem *ioaddr = tp->mmio_addr; 897
876 u8 status; 898 return mii_ethtool_gset(&tp->mii, cmd);
877
878 cmd->supported = SUPPORTED_10baseT_Half |
879 SUPPORTED_10baseT_Full |
880 SUPPORTED_100baseT_Half |
881 SUPPORTED_100baseT_Full |
882 SUPPORTED_1000baseT_Full |
883 SUPPORTED_Autoneg |
884 SUPPORTED_TP;
885
886 cmd->autoneg = 1;
887 cmd->advertising = ADVERTISED_TP | ADVERTISED_Autoneg;
888
889 if (tp->phy_auto_nego_reg & ADVERTISE_10HALF)
890 cmd->advertising |= ADVERTISED_10baseT_Half;
891 if (tp->phy_auto_nego_reg & ADVERTISE_10FULL)
892 cmd->advertising |= ADVERTISED_10baseT_Full;
893 if (tp->phy_auto_nego_reg & ADVERTISE_100HALF)
894 cmd->advertising |= ADVERTISED_100baseT_Half;
895 if (tp->phy_auto_nego_reg & ADVERTISE_100FULL)
896 cmd->advertising |= ADVERTISED_100baseT_Full;
897 if (tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL)
898 cmd->advertising |= ADVERTISED_1000baseT_Full;
899
900 status = RTL_R8(PHYstatus);
901
902 if (status & _1000bpsF)
903 cmd->speed = SPEED_1000;
904 else if (status & _100bps)
905 cmd->speed = SPEED_100;
906 else if (status & _10bps)
907 cmd->speed = SPEED_10;
908
909 if (status & TxFlowCtrl)
910 cmd->advertising |= ADVERTISED_Asym_Pause;
911 if (status & RxFlowCtrl)
912 cmd->advertising |= ADVERTISED_Pause;
913
914 cmd->duplex = ((status & _1000bpsF) || (status & FullDup)) ?
915 DUPLEX_FULL : DUPLEX_HALF;
916} 899}
917 900
918static int rtl8169_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) 901static int rtl8169_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
919{ 902{
920 struct rtl8169_private *tp = netdev_priv(dev); 903 struct rtl8169_private *tp = netdev_priv(dev);
921 unsigned long flags; 904 unsigned long flags;
905 int rc;
922 906
923 spin_lock_irqsave(&tp->lock, flags); 907 spin_lock_irqsave(&tp->lock, flags);
924 908
925 tp->get_settings(dev, cmd); 909 rc = tp->get_settings(dev, cmd);
926 910
927 spin_unlock_irqrestore(&tp->lock, flags); 911 spin_unlock_irqrestore(&tp->lock, flags);
928 return 0; 912 return rc;
929} 913}
930 914
931static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs, 915static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs,
@@ -1513,7 +1497,7 @@ static const struct rtl_cfg_info {
1513 unsigned int align; 1497 unsigned int align;
1514 u16 intr_event; 1498 u16 intr_event;
1515 u16 napi_event; 1499 u16 napi_event;
1516 unsigned msi; 1500 unsigned features;
1517} rtl_cfg_infos [] = { 1501} rtl_cfg_infos [] = {
1518 [RTL_CFG_0] = { 1502 [RTL_CFG_0] = {
1519 .hw_start = rtl_hw_start_8169, 1503 .hw_start = rtl_hw_start_8169,
@@ -1522,7 +1506,7 @@ static const struct rtl_cfg_info {
1522 .intr_event = SYSErr | LinkChg | RxOverflow | 1506 .intr_event = SYSErr | LinkChg | RxOverflow |
1523 RxFIFOOver | TxErr | TxOK | RxOK | RxErr, 1507 RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
1524 .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow, 1508 .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
1525 .msi = 0 1509 .features = RTL_FEATURE_GMII
1526 }, 1510 },
1527 [RTL_CFG_1] = { 1511 [RTL_CFG_1] = {
1528 .hw_start = rtl_hw_start_8168, 1512 .hw_start = rtl_hw_start_8168,
@@ -1531,7 +1515,7 @@ static const struct rtl_cfg_info {
1531 .intr_event = SYSErr | LinkChg | RxOverflow | 1515 .intr_event = SYSErr | LinkChg | RxOverflow |
1532 TxErr | TxOK | RxOK | RxErr, 1516 TxErr | TxOK | RxOK | RxErr,
1533 .napi_event = TxErr | TxOK | RxOK | RxOverflow, 1517 .napi_event = TxErr | TxOK | RxOK | RxOverflow,
1534 .msi = RTL_FEATURE_MSI 1518 .features = RTL_FEATURE_GMII | RTL_FEATURE_MSI
1535 }, 1519 },
1536 [RTL_CFG_2] = { 1520 [RTL_CFG_2] = {
1537 .hw_start = rtl_hw_start_8101, 1521 .hw_start = rtl_hw_start_8101,
@@ -1540,7 +1524,7 @@ static const struct rtl_cfg_info {
1540 .intr_event = SYSErr | LinkChg | RxOverflow | PCSTimeout | 1524 .intr_event = SYSErr | LinkChg | RxOverflow | PCSTimeout |
1541 RxFIFOOver | TxErr | TxOK | RxOK | RxErr, 1525 RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
1542 .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow, 1526 .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
1543 .msi = RTL_FEATURE_MSI 1527 .features = RTL_FEATURE_MSI
1544 } 1528 }
1545}; 1529};
1546 1530
@@ -1552,7 +1536,7 @@ static unsigned rtl_try_msi(struct pci_dev *pdev, void __iomem *ioaddr,
1552 u8 cfg2; 1536 u8 cfg2;
1553 1537
1554 cfg2 = RTL_R8(Config2) & ~MSIEnable; 1538 cfg2 = RTL_R8(Config2) & ~MSIEnable;
1555 if (cfg->msi) { 1539 if (cfg->features & RTL_FEATURE_MSI) {
1556 if (pci_enable_msi(pdev)) { 1540 if (pci_enable_msi(pdev)) {
1557 dev_info(&pdev->dev, "no MSI. Back to INTx.\n"); 1541 dev_info(&pdev->dev, "no MSI. Back to INTx.\n");
1558 } else { 1542 } else {
@@ -1578,6 +1562,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
1578 const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data; 1562 const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data;
1579 const unsigned int region = cfg->region; 1563 const unsigned int region = cfg->region;
1580 struct rtl8169_private *tp; 1564 struct rtl8169_private *tp;
1565 struct mii_if_info *mii;
1581 struct net_device *dev; 1566 struct net_device *dev;
1582 void __iomem *ioaddr; 1567 void __iomem *ioaddr;
1583 unsigned int i; 1568 unsigned int i;
@@ -1602,6 +1587,14 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
1602 tp->pci_dev = pdev; 1587 tp->pci_dev = pdev;
1603 tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT); 1588 tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT);
1604 1589
1590 mii = &tp->mii;
1591 mii->dev = dev;
1592 mii->mdio_read = rtl_mdio_read;
1593 mii->mdio_write = rtl_mdio_write;
1594 mii->phy_id_mask = 0x1f;
1595 mii->reg_num_mask = 0x1f;
1596 mii->supports_gmii = !!(cfg->features & RTL_FEATURE_GMII);
1597
1605 /* enable device (incl. PCI PM wakeup and hotplug setup) */ 1598 /* enable device (incl. PCI PM wakeup and hotplug setup) */
1606 rc = pci_enable_device(pdev); 1599 rc = pci_enable_device(pdev);
1607 if (rc < 0) { 1600 if (rc < 0) {