The SFP driver was reading up to 256 bytes of I2C data from the SFP module in a single chunk. However, some I2C controllers do not support reading that many bytes in a single transaction. Change to use a more compatible 16-byte chunk size, since this is not performance critical.
Signed-off-by: Robert Hancock <hanc...@sedsystems.ca> --- drivers/net/phy/sfp.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c index 6b6c83d..23a40a7 100644 --- a/drivers/net/phy/sfp.c +++ b/drivers/net/phy/sfp.c @@ -1651,7 +1651,7 @@ static int sfp_module_info(struct sfp *sfp, struct ethtool_modinfo *modinfo) static int sfp_module_eeprom(struct sfp *sfp, struct ethtool_eeprom *ee, u8 *data) { - unsigned int first, last, len; + unsigned int first, last; int ret; if (ee->len == 0) @@ -1659,26 +1659,36 @@ static int sfp_module_eeprom(struct sfp *sfp, struct ethtool_eeprom *ee, first = ee->offset; last = ee->offset + ee->len; - if (first < ETH_MODULE_SFF_8079_LEN) { - len = min_t(unsigned int, last, ETH_MODULE_SFF_8079_LEN); - len -= first; - ret = sfp_read(sfp, false, first, data, len); + while (first < last) { + bool a2; + unsigned int this_addr, len; + + if (first < ETH_MODULE_SFF_8079_LEN) { + len = min_t(unsigned int, last, + ETH_MODULE_SFF_8079_LEN); + len -= first; + a2 = false; + this_addr = first; + } else { + len = min_t(unsigned int, last, + ETH_MODULE_SFF_8472_LEN); + len -= first; + a2 = true; + this_addr = first - ETH_MODULE_SFF_8079_LEN; + } + /* Some I2C adapters cannot read 256 bytes in a single read. + * Use a smaller chunk size to ensure we are within limits. + */ + len = min_t(unsigned int, len, 16); + + ret = sfp_read(sfp, a2, this_addr, data, len); if (ret < 0) return ret; first += len; data += len; } - if (first < ETH_MODULE_SFF_8472_LEN && last > ETH_MODULE_SFF_8079_LEN) { - len = min_t(unsigned int, last, ETH_MODULE_SFF_8472_LEN); - len -= first; - first -= ETH_MODULE_SFF_8079_LEN; - - ret = sfp_read(sfp, true, first, data, len); - if (ret < 0) - return ret; - } return 0; } -- 1.8.3.1