net: lan78xx: Fix to write to OTP(One Time Programmable) per magic number.

This patch fixes a bug writing to EEPROM in lan78xx_ethtool_set_eeprom()
when asked to write to OTP.

Signed-off-by: Woojung Huh <woojung.huh@microchip.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Woojung.Huh@microchip.com 2016-01-05 17:29:59 +00:00 committed by David S. Miller
parent 51cb67c0b0
commit 9fb6066d0d
1 changed files with 54 additions and 1 deletions

View File

@ -603,6 +603,59 @@ static int lan78xx_read_raw_otp(struct lan78xx_net *dev, u32 offset,
return 0;
}
static int lan78xx_write_raw_otp(struct lan78xx_net *dev, u32 offset,
u32 length, u8 *data)
{
int i;
int ret;
u32 buf;
unsigned long timeout;
ret = lan78xx_read_reg(dev, OTP_PWR_DN, &buf);
if (buf & OTP_PWR_DN_PWRDN_N_) {
/* clear it and wait to be cleared */
ret = lan78xx_write_reg(dev, OTP_PWR_DN, 0);
timeout = jiffies + HZ;
do {
udelay(1);
ret = lan78xx_read_reg(dev, OTP_PWR_DN, &buf);
if (time_after(jiffies, timeout)) {
netdev_warn(dev->net,
"timeout on OTP_PWR_DN completion");
return -EIO;
}
} while (buf & OTP_PWR_DN_PWRDN_N_);
}
/* set to BYTE program mode */
ret = lan78xx_write_reg(dev, OTP_PRGM_MODE, OTP_PRGM_MODE_BYTE_);
for (i = 0; i < length; i++) {
ret = lan78xx_write_reg(dev, OTP_ADDR1,
((offset + i) >> 8) & OTP_ADDR1_15_11);
ret = lan78xx_write_reg(dev, OTP_ADDR2,
((offset + i) & OTP_ADDR2_10_3));
ret = lan78xx_write_reg(dev, OTP_PRGM_DATA, data[i]);
ret = lan78xx_write_reg(dev, OTP_TST_CMD, OTP_TST_CMD_PRGVRFY_);
ret = lan78xx_write_reg(dev, OTP_CMD_GO, OTP_CMD_GO_GO_);
timeout = jiffies + HZ;
do {
udelay(1);
ret = lan78xx_read_reg(dev, OTP_STATUS, &buf);
if (time_after(jiffies, timeout)) {
netdev_warn(dev->net,
"Timeout on OTP_STATUS completion");
return -EIO;
}
} while (buf & OTP_STATUS_BUSY_);
}
return 0;
}
static int lan78xx_read_otp(struct lan78xx_net *dev, u32 offset,
u32 length, u8 *data)
{
@ -969,7 +1022,7 @@ static int lan78xx_ethtool_set_eeprom(struct net_device *netdev,
(ee->offset == 0) &&
(ee->len == 512) &&
(data[0] == OTP_INDICATOR_1))
return lan78xx_write_raw_eeprom(dev, ee->offset, ee->len, data);
return lan78xx_write_raw_otp(dev, ee->offset, ee->len, data);
return -EINVAL;
}