From b1f14659d9df2263b9b5b4accbfed2780eaef584 Mon Sep 17 00:00:00 2001 From: Ulrich Langenbach Date: Thu, 11 Aug 2022 11:35:22 +0200 Subject: [PATCH] modules/mqnic: sfp module eeprom i2c address adjustment for full access * the optical diagnostics data is provided by the SFP modules using another I2C address, which must be set via the I2C client --- modules/mqnic/mqnic_ethtool.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/modules/mqnic/mqnic_ethtool.c b/modules/mqnic/mqnic_ethtool.c index 60e76c76b..f99699e71 100644 --- a/modules/mqnic/mqnic_ethtool.c +++ b/modules/mqnic/mqnic_ethtool.c @@ -327,6 +327,8 @@ static int mqnic_query_module_eeprom_by_page(struct net_device *ndev, { int module_id; u8 d; + int ret; + unsigned short orig_i2c_addr; module_id = mqnic_query_module_id(ndev); @@ -374,8 +376,23 @@ static int mqnic_query_module_eeprom_by_page(struct net_device *ndev, return -EINVAL; } + // set i2c address of the mod_i2c_client + // This code section should not be called concurrently since the IOCTL + // handler for ethtool operations is called under the RTNL lock. + // In addition the i2c_client is used only within code inside this lock. + if (!priv->mod_i2c_client) + return -EINVAL; + + orig_i2c_addr = priv->mod_i2c_client->addr; + priv->mod_i2c_client->addr = i2c_addr; + // read data - return mqnic_read_module_eeprom(ndev, offset, len, data); + ret = mqnic_read_module_eeprom(ndev, offset, len, data); + + // reset i2c addr + priv->mod_i2c_client->addr = orig_i2c_addr; + + return ret; } static int mqnic_query_module_eeprom(struct net_device *ndev,