Commit e9c9692c authored by Scott W Taylor's avatar Scott W Taylor Committed by Tony Nguyen
Browse files

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: default avatarScott W Taylor <scott.w.taylor@intel.com>
Tested-by: default avatarTony Brelinski <tonyx.brelinski@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent d59684a0
Loading
Loading
Loading
Loading
+39 −10
Original line number Diff line number Diff line
@@ -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;
}