aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/qlogic/qede/qede_ethtool.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
index f4a0f8ff8261..b37857f3f950 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
@@ -1780,6 +1780,92 @@ static int qede_set_eee(struct net_device *dev, struct ethtool_eee *edata)
1780 return 0; 1780 return 0;
1781} 1781}
1782 1782
1783static int qede_get_module_info(struct net_device *dev,
1784 struct ethtool_modinfo *modinfo)
1785{
1786 struct qede_dev *edev = netdev_priv(dev);
1787 u8 buf[4];
1788 int rc;
1789
1790 /* Read first 4 bytes to find the sfp type */
1791 rc = edev->ops->common->read_module_eeprom(edev->cdev, buf,
1792 QED_I2C_DEV_ADDR_A0, 0, 4);
1793 if (rc) {
1794 DP_ERR(edev, "Failed reading EEPROM data %d\n", rc);
1795 return rc;
1796 }
1797
1798 switch (buf[0]) {
1799 case 0x3: /* SFP, SFP+, SFP-28 */
1800 modinfo->type = ETH_MODULE_SFF_8472;
1801 modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
1802 break;
1803 case 0xc: /* QSFP */
1804 case 0xd: /* QSFP+ */
1805 modinfo->type = ETH_MODULE_SFF_8436;
1806 modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN;
1807 break;
1808 case 0x11: /* QSFP-28 */
1809 modinfo->type = ETH_MODULE_SFF_8636;
1810 modinfo->eeprom_len = ETH_MODULE_SFF_8636_LEN;
1811 break;
1812 default:
1813 DP_ERR(edev, "Unknown transceiver type 0x%x\n", buf[0]);
1814 return -EINVAL;
1815 }
1816
1817 return 0;
1818}
1819
1820static int qede_get_module_eeprom(struct net_device *dev,
1821 struct ethtool_eeprom *ee, u8 *data)
1822{
1823 struct qede_dev *edev = netdev_priv(dev);
1824 u32 start_addr = ee->offset, size = 0;
1825 u8 *buf = data;
1826 int rc = 0;
1827
1828 /* Read A0 section */
1829 if (ee->offset < ETH_MODULE_SFF_8079_LEN) {
1830 /* Limit transfer size to the A0 section boundary */
1831 if (ee->offset + ee->len > ETH_MODULE_SFF_8079_LEN)
1832 size = ETH_MODULE_SFF_8079_LEN - ee->offset;
1833 else
1834 size = ee->len;
1835
1836 rc = edev->ops->common->read_module_eeprom(edev->cdev, buf,
1837 QED_I2C_DEV_ADDR_A0,
1838 start_addr, size);
1839 if (rc) {
1840 DP_ERR(edev, "Failed reading A0 section %d\n", rc);
1841 return rc;
1842 }
1843
1844 buf += size;
1845 start_addr += size;
1846 }
1847
1848 /* Read A2 section */
1849 if (start_addr >= ETH_MODULE_SFF_8079_LEN &&
1850 start_addr < ETH_MODULE_SFF_8472_LEN) {
1851 size = ee->len - size;
1852 /* Limit transfer size to the A2 section boundary */
1853 if (start_addr + size > ETH_MODULE_SFF_8472_LEN)
1854 size = ETH_MODULE_SFF_8472_LEN - start_addr;
1855 start_addr -= ETH_MODULE_SFF_8079_LEN;
1856 rc = edev->ops->common->read_module_eeprom(edev->cdev, buf,
1857 QED_I2C_DEV_ADDR_A2,
1858 start_addr, size);
1859 if (rc) {
1860 DP_VERBOSE(edev, QED_MSG_DEBUG,
1861 "Failed reading A2 section %d\n", rc);
1862 return 0;
1863 }
1864 }
1865
1866 return rc;
1867}
1868
1783static const struct ethtool_ops qede_ethtool_ops = { 1869static const struct ethtool_ops qede_ethtool_ops = {
1784 .get_link_ksettings = qede_get_link_ksettings, 1870 .get_link_ksettings = qede_get_link_ksettings,
1785 .set_link_ksettings = qede_set_link_ksettings, 1871 .set_link_ksettings = qede_set_link_ksettings,
@@ -1813,6 +1899,8 @@ static const struct ethtool_ops qede_ethtool_ops = {
1813 .get_channels = qede_get_channels, 1899 .get_channels = qede_get_channels,
1814 .set_channels = qede_set_channels, 1900 .set_channels = qede_set_channels,
1815 .self_test = qede_self_test, 1901 .self_test = qede_self_test,
1902 .get_module_info = qede_get_module_info,
1903 .get_module_eeprom = qede_get_module_eeprom,
1816 .get_eee = qede_get_eee, 1904 .get_eee = qede_get_eee,
1817 .set_eee = qede_set_eee, 1905 .set_eee = qede_set_eee,
1818 1906