Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a0db7d10 authored by Woojung.Huh@microchip.com's avatar Woojung.Huh@microchip.com Committed by David S. Miller
Browse files

lan78xx: Add to handle mux control per chip id



Depends on chip, some EEPROM pins are muxed with LED function.
Disable & restore LED function to access EEPROM.

Signed-off-by: default avatarWoojung Huh <woojung.huh@microchip.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e4953910
Loading
Loading
Loading
Loading
+71 −27
Original line number Original line Diff line number Diff line
@@ -462,32 +462,53 @@ static int lan78xx_read_raw_eeprom(struct lan78xx_net *dev, u32 offset,
				   u32 length, u8 *data)
				   u32 length, u8 *data)
{
{
	u32 val;
	u32 val;
	u32 saved;
	int i, ret;
	int i, ret;
	int retval;


	ret = lan78xx_eeprom_confirm_not_busy(dev);
	/* depends on chip, some EEPROM pins are muxed with LED function.
	if (ret)
	 * disable & restore LED function to access EEPROM.
		return ret;
	 */
	ret = lan78xx_read_reg(dev, HW_CFG, &val);
	saved = val;
	if ((dev->devid & ID_REV_CHIP_ID_MASK_) == 0x78000000) {
		val &= ~(HW_CFG_LED1_EN_ | HW_CFG_LED0_EN_);
		ret = lan78xx_write_reg(dev, HW_CFG, val);
	}

	retval = lan78xx_eeprom_confirm_not_busy(dev);
	if (retval)
		return retval;


	for (i = 0; i < length; i++) {
	for (i = 0; i < length; i++) {
		val = E2P_CMD_EPC_BUSY_ | E2P_CMD_EPC_CMD_READ_;
		val = E2P_CMD_EPC_BUSY_ | E2P_CMD_EPC_CMD_READ_;
		val |= (offset & E2P_CMD_EPC_ADDR_MASK_);
		val |= (offset & E2P_CMD_EPC_ADDR_MASK_);
		ret = lan78xx_write_reg(dev, E2P_CMD, val);
		ret = lan78xx_write_reg(dev, E2P_CMD, val);
		if (unlikely(ret < 0))
		if (unlikely(ret < 0)) {
			return -EIO;
			retval = -EIO;
			goto exit;
		}


		ret = lan78xx_wait_eeprom(dev);
		retval = lan78xx_wait_eeprom(dev);
		if (ret < 0)
		if (retval < 0)
			return ret;
			goto exit;


		ret = lan78xx_read_reg(dev, E2P_DATA, &val);
		ret = lan78xx_read_reg(dev, E2P_DATA, &val);
		if (unlikely(ret < 0))
		if (unlikely(ret < 0)) {
			return -EIO;
			retval = -EIO;
			goto exit;
		}


		data[i] = val & 0xFF;
		data[i] = val & 0xFF;
		offset++;
		offset++;
	}
	}


	return 0;
	retval = 0;
exit:
	if ((dev->devid & ID_REV_CHIP_ID_MASK_) == 0x78000000)
		ret = lan78xx_write_reg(dev, HW_CFG, saved);

	return retval;
}
}


static int lan78xx_read_eeprom(struct lan78xx_net *dev, u32 offset,
static int lan78xx_read_eeprom(struct lan78xx_net *dev, u32 offset,
@@ -509,44 +530,67 @@ static int lan78xx_write_raw_eeprom(struct lan78xx_net *dev, u32 offset,
				    u32 length, u8 *data)
				    u32 length, u8 *data)
{
{
	u32 val;
	u32 val;
	u32 saved;
	int i, ret;
	int i, ret;
	int retval;


	ret = lan78xx_eeprom_confirm_not_busy(dev);
	/* depends on chip, some EEPROM pins are muxed with LED function.
	if (ret)
	 * disable & restore LED function to access EEPROM.
		return ret;
	 */
	ret = lan78xx_read_reg(dev, HW_CFG, &val);
	saved = val;
	if ((dev->devid & ID_REV_CHIP_ID_MASK_) == 0x78000000) {
		val &= ~(HW_CFG_LED1_EN_ | HW_CFG_LED0_EN_);
		ret = lan78xx_write_reg(dev, HW_CFG, val);
	}

	retval = lan78xx_eeprom_confirm_not_busy(dev);
	if (retval)
		goto exit;


	/* Issue write/erase enable command */
	/* Issue write/erase enable command */
	val = E2P_CMD_EPC_BUSY_ | E2P_CMD_EPC_CMD_EWEN_;
	val = E2P_CMD_EPC_BUSY_ | E2P_CMD_EPC_CMD_EWEN_;
	ret = lan78xx_write_reg(dev, E2P_CMD, val);
	ret = lan78xx_write_reg(dev, E2P_CMD, val);
	if (unlikely(ret < 0))
	if (unlikely(ret < 0)) {
		return -EIO;
		retval = -EIO;
		goto exit;
	}


	ret = lan78xx_wait_eeprom(dev);
	retval = lan78xx_wait_eeprom(dev);
	if (ret < 0)
	if (retval < 0)
		return ret;
		goto exit;


	for (i = 0; i < length; i++) {
	for (i = 0; i < length; i++) {
		/* Fill data register */
		/* Fill data register */
		val = data[i];
		val = data[i];
		ret = lan78xx_write_reg(dev, E2P_DATA, val);
		ret = lan78xx_write_reg(dev, E2P_DATA, val);
		if (ret < 0)
		if (ret < 0) {
			return ret;
			retval = -EIO;
			goto exit;
		}


		/* Send "write" command */
		/* Send "write" command */
		val = E2P_CMD_EPC_BUSY_ | E2P_CMD_EPC_CMD_WRITE_;
		val = E2P_CMD_EPC_BUSY_ | E2P_CMD_EPC_CMD_WRITE_;
		val |= (offset & E2P_CMD_EPC_ADDR_MASK_);
		val |= (offset & E2P_CMD_EPC_ADDR_MASK_);
		ret = lan78xx_write_reg(dev, E2P_CMD, val);
		ret = lan78xx_write_reg(dev, E2P_CMD, val);
		if (ret < 0)
		if (ret < 0) {
			return ret;
			retval = -EIO;
			goto exit;
		}


		ret = lan78xx_wait_eeprom(dev);
		retval = lan78xx_wait_eeprom(dev);
		if (ret < 0)
		if (retval < 0)
			return ret;
			goto exit;


		offset++;
		offset++;
	}
	}


	return 0;
	retval = 0;
exit:
	if ((dev->devid & ID_REV_CHIP_ID_MASK_) == 0x78000000)
		ret = lan78xx_write_reg(dev, HW_CFG, saved);

	return retval;
}
}


static int lan78xx_read_raw_otp(struct lan78xx_net *dev, u32 offset,
static int lan78xx_read_raw_otp(struct lan78xx_net *dev, u32 offset,