diff options
-rw-r--r-- | include/linux/phy.h | 9 | ||||
-rw-r--r-- | net/core/ethtool.c | 45 |
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 | ||
1600 | static 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 | |||
1600 | static int ethtool_get_module_info(struct net_device *dev, | 1615 | static 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 | ||
1634 | static 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 | |||
1623 | static int ethtool_get_module_eeprom(struct net_device *dev, | 1649 | static 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 | ||