ice: Reimplement module reads used by ethtool
There was an excessive increment of the QSFP page, which is now fixed. Additionally, this new update now reads 8 bytes at a time and will retry each request if the module/bus is busy. Also, prevent reading from upper pages if module does not support those pages. Signed-off-by: Scott W Taylor <scott.w.taylor@intel.com> Tested-by: Tony Brelinski <tonyx.brelinski@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
This commit is contained in:
parent
d59684a07e
commit
e9c9692c8a
|
@ -3914,30 +3914,33 @@ ice_get_module_eeprom(struct net_device *netdev,
|
|||
struct ethtool_eeprom *ee, u8 *data)
|
||||
{
|
||||
struct ice_netdev_priv *np = netdev_priv(netdev);
|
||||
#define SFF_READ_BLOCK_SIZE 8
|
||||
u8 value[SFF_READ_BLOCK_SIZE] = { 0 };
|
||||
u8 addr = ICE_I2C_EEPROM_DEV_ADDR;
|
||||
struct ice_vsi *vsi = np->vsi;
|
||||
struct ice_pf *pf = vsi->back;
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
enum ice_status status;
|
||||
bool is_sfp = false;
|
||||
unsigned int i;
|
||||
unsigned int i, j;
|
||||
u16 offset = 0;
|
||||
u8 value = 0;
|
||||
u8 page = 0;
|
||||
|
||||
if (!ee || !ee->len || !data)
|
||||
return -EINVAL;
|
||||
|
||||
status = ice_aq_sff_eeprom(hw, 0, addr, offset, page, 0, &value, 1, 0,
|
||||
status = ice_aq_sff_eeprom(hw, 0, addr, offset, page, 0, value, 1, 0,
|
||||
NULL);
|
||||
if (status)
|
||||
return -EIO;
|
||||
|
||||
if (value == ICE_MODULE_TYPE_SFP)
|
||||
if (value[0] == ICE_MODULE_TYPE_SFP)
|
||||
is_sfp = true;
|
||||
|
||||
for (i = 0; i < ee->len; i++) {
|
||||
memset(data, 0, ee->len);
|
||||
for (i = 0; i < ee->len; i += SFF_READ_BLOCK_SIZE) {
|
||||
offset = i + ee->offset;
|
||||
page = 0;
|
||||
|
||||
/* Check if we need to access the other memory page */
|
||||
if (is_sfp) {
|
||||
|
@ -3953,11 +3956,37 @@ ice_get_module_eeprom(struct net_device *netdev,
|
|||
}
|
||||
}
|
||||
|
||||
status = ice_aq_sff_eeprom(hw, 0, addr, offset, page, !is_sfp,
|
||||
&value, 1, 0, NULL);
|
||||
if (status)
|
||||
value = 0;
|
||||
data[i] = value;
|
||||
/* Bit 2 of EEPROM address 0x02 declares upper
|
||||
* pages are disabled on QSFP modules.
|
||||
* SFP modules only ever use page 0.
|
||||
*/
|
||||
if (page == 0 || !(data[0x2] & 0x4)) {
|
||||
/* If i2c bus is busy due to slow page change or
|
||||
* link management access, call can fail. This is normal.
|
||||
* So we retry this a few times.
|
||||
*/
|
||||
for (j = 0; j < 4; j++) {
|
||||
status = ice_aq_sff_eeprom(hw, 0, addr, offset, page,
|
||||
!is_sfp, value,
|
||||
SFF_READ_BLOCK_SIZE,
|
||||
0, NULL);
|
||||
netdev_dbg(netdev, "SFF %02X %02X %02X %X = %02X%02X%02X%02X.%02X%02X%02X%02X (%X)\n",
|
||||
addr, offset, page, is_sfp,
|
||||
value[0], value[1], value[2], value[3],
|
||||
value[4], value[5], value[6], value[7],
|
||||
status);
|
||||
if (status) {
|
||||
usleep_range(1500, 2500);
|
||||
memset(value, 0, SFF_READ_BLOCK_SIZE);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Make sure we have enough room for the new block */
|
||||
if ((i + SFF_READ_BLOCK_SIZE) < ee->len)
|
||||
memcpy(data + i, value, SFF_READ_BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue