aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/phy.h9
-rw-r--r--net/core/ethtool.c45
2 files changed, 43 insertions, 11 deletions
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 22af8f8f5802..9c189a1fa3a2 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -565,6 +565,15 @@ struct phy_driver {
565 void (*write_mmd_indirect)(struct phy_device *dev, int ptrad, 565 void (*write_mmd_indirect)(struct phy_device *dev, int ptrad,
566 int devnum, int regnum, u32 val); 566 int devnum, int regnum, u32 val);
567 567
568 /* Get the size and type of the eeprom contained within a plug-in
569 * module */
570 int (*module_info)(struct phy_device *dev,
571 struct ethtool_modinfo *modinfo);
572
573 /* Get the eeprom information from the plug-in module */
574 int (*module_eeprom)(struct phy_device *dev,
575 struct ethtool_eeprom *ee, u8 *data);
576
568 struct device_driver driver; 577 struct device_driver driver;
569}; 578};
570#define to_phy_driver(d) container_of(d, struct phy_driver, driver) 579#define to_phy_driver(d) container_of(d, struct phy_driver, driver)
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 550892cd6b3f..91f74f3eb204 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -1597,20 +1597,31 @@ static int ethtool_get_ts_info(struct net_device *dev, void __user *useraddr)
1597 return err; 1597 return err;
1598} 1598}
1599 1599
1600static int __ethtool_get_module_info(struct net_device *dev,
1601 struct ethtool_modinfo *modinfo)
1602{
1603 const struct ethtool_ops *ops = dev->ethtool_ops;
1604 struct phy_device *phydev = dev->phydev;
1605
1606 if (phydev && phydev->drv && phydev->drv->module_info)
1607 return phydev->drv->module_info(phydev, modinfo);
1608
1609 if (ops->get_module_info)
1610 return ops->get_module_info(dev, modinfo);
1611
1612 return -EOPNOTSUPP;
1613}
1614
1600static int ethtool_get_module_info(struct net_device *dev, 1615static int ethtool_get_module_info(struct net_device *dev,
1601 void __user *useraddr) 1616 void __user *useraddr)
1602{ 1617{
1603 int ret; 1618 int ret;
1604 struct ethtool_modinfo modinfo; 1619 struct ethtool_modinfo modinfo;
1605 const struct ethtool_ops *ops = dev->ethtool_ops;
1606
1607 if (!ops->get_module_info)
1608 return -EOPNOTSUPP;
1609 1620
1610 if (copy_from_user(&modinfo, useraddr, sizeof(modinfo))) 1621 if (copy_from_user(&modinfo, useraddr, sizeof(modinfo)))
1611 return -EFAULT; 1622 return -EFAULT;
1612 1623
1613 ret = ops->get_module_info(dev, &modinfo); 1624 ret = __ethtool_get_module_info(dev, &modinfo);
1614 if (ret) 1625 if (ret)
1615 return ret; 1626 return ret;
1616 1627
@@ -1620,21 +1631,33 @@ static int ethtool_get_module_info(struct net_device *dev,
1620 return 0; 1631 return 0;
1621} 1632}
1622 1633
1634static int __ethtool_get_module_eeprom(struct net_device *dev,
1635 struct ethtool_eeprom *ee, u8 *data)
1636{
1637 const struct ethtool_ops *ops = dev->ethtool_ops;
1638 struct phy_device *phydev = dev->phydev;
1639
1640 if (phydev && phydev->drv && phydev->drv->module_eeprom)
1641 return phydev->drv->module_eeprom(phydev, ee, data);
1642
1643 if (ops->get_module_eeprom)
1644 return ops->get_module_eeprom(dev, ee, data);
1645
1646 return -EOPNOTSUPP;
1647}
1648
1623static int ethtool_get_module_eeprom(struct net_device *dev, 1649static int ethtool_get_module_eeprom(struct net_device *dev,
1624 void __user *useraddr) 1650 void __user *useraddr)
1625{ 1651{
1626 int ret; 1652 int ret;
1627 struct ethtool_modinfo modinfo; 1653 struct ethtool_modinfo modinfo;
1628 const struct ethtool_ops *ops = dev->ethtool_ops;
1629
1630 if (!ops->get_module_info || !ops->get_module_eeprom)
1631 return -EOPNOTSUPP;
1632 1654
1633 ret = ops->get_module_info(dev, &modinfo); 1655 ret = __ethtool_get_module_info(dev, &modinfo);
1634 if (ret) 1656 if (ret)
1635 return ret; 1657 return ret;
1636 1658
1637 return ethtool_get_any_eeprom(dev, useraddr, ops->get_module_eeprom, 1659 return ethtool_get_any_eeprom(dev, useraddr,
1660 __ethtool_get_module_eeprom,
1638 modinfo.eeprom_len); 1661 modinfo.eeprom_len);
1639} 1662}
1640 1663