tg3: Move tg3_nvram_write_block functions
This patch moves the tg3_nvram_write_block functions higher in the file to eliminate a prototype. Signed-off-by: Matt Carlson <mcarlson@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
ccd5ba9db5
commit
dbe9b92a60
@@ -2978,6 +2978,256 @@ static int tg3_nvram_read_be32(struct tg3 *tp, u32 offset, __be32 *val)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int tg3_nvram_write_block_using_eeprom(struct tg3 *tp,
|
||||||
|
u32 offset, u32 len, u8 *buf)
|
||||||
|
{
|
||||||
|
int i, j, rc = 0;
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i += 4) {
|
||||||
|
u32 addr;
|
||||||
|
__be32 data;
|
||||||
|
|
||||||
|
addr = offset + i;
|
||||||
|
|
||||||
|
memcpy(&data, buf + i, 4);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The SEEPROM interface expects the data to always be opposite
|
||||||
|
* the native endian format. We accomplish this by reversing
|
||||||
|
* all the operations that would have been performed on the
|
||||||
|
* data from a call to tg3_nvram_read_be32().
|
||||||
|
*/
|
||||||
|
tw32(GRC_EEPROM_DATA, swab32(be32_to_cpu(data)));
|
||||||
|
|
||||||
|
val = tr32(GRC_EEPROM_ADDR);
|
||||||
|
tw32(GRC_EEPROM_ADDR, val | EEPROM_ADDR_COMPLETE);
|
||||||
|
|
||||||
|
val &= ~(EEPROM_ADDR_ADDR_MASK | EEPROM_ADDR_DEVID_MASK |
|
||||||
|
EEPROM_ADDR_READ);
|
||||||
|
tw32(GRC_EEPROM_ADDR, val |
|
||||||
|
(0 << EEPROM_ADDR_DEVID_SHIFT) |
|
||||||
|
(addr & EEPROM_ADDR_ADDR_MASK) |
|
||||||
|
EEPROM_ADDR_START |
|
||||||
|
EEPROM_ADDR_WRITE);
|
||||||
|
|
||||||
|
for (j = 0; j < 1000; j++) {
|
||||||
|
val = tr32(GRC_EEPROM_ADDR);
|
||||||
|
|
||||||
|
if (val & EEPROM_ADDR_COMPLETE)
|
||||||
|
break;
|
||||||
|
msleep(1);
|
||||||
|
}
|
||||||
|
if (!(val & EEPROM_ADDR_COMPLETE)) {
|
||||||
|
rc = -EBUSY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* offset and length are dword aligned */
|
||||||
|
static int tg3_nvram_write_block_unbuffered(struct tg3 *tp, u32 offset, u32 len,
|
||||||
|
u8 *buf)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
u32 pagesize = tp->nvram_pagesize;
|
||||||
|
u32 pagemask = pagesize - 1;
|
||||||
|
u32 nvram_cmd;
|
||||||
|
u8 *tmp;
|
||||||
|
|
||||||
|
tmp = kmalloc(pagesize, GFP_KERNEL);
|
||||||
|
if (tmp == NULL)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
while (len) {
|
||||||
|
int j;
|
||||||
|
u32 phy_addr, page_off, size;
|
||||||
|
|
||||||
|
phy_addr = offset & ~pagemask;
|
||||||
|
|
||||||
|
for (j = 0; j < pagesize; j += 4) {
|
||||||
|
ret = tg3_nvram_read_be32(tp, phy_addr + j,
|
||||||
|
(__be32 *) (tmp + j));
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
|
|
||||||
|
page_off = offset & pagemask;
|
||||||
|
size = pagesize;
|
||||||
|
if (len < size)
|
||||||
|
size = len;
|
||||||
|
|
||||||
|
len -= size;
|
||||||
|
|
||||||
|
memcpy(tmp + page_off, buf, size);
|
||||||
|
|
||||||
|
offset = offset + (pagesize - page_off);
|
||||||
|
|
||||||
|
tg3_enable_nvram_access(tp);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Before we can erase the flash page, we need
|
||||||
|
* to issue a special "write enable" command.
|
||||||
|
*/
|
||||||
|
nvram_cmd = NVRAM_CMD_WREN | NVRAM_CMD_GO | NVRAM_CMD_DONE;
|
||||||
|
|
||||||
|
if (tg3_nvram_exec_cmd(tp, nvram_cmd))
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Erase the target page */
|
||||||
|
tw32(NVRAM_ADDR, phy_addr);
|
||||||
|
|
||||||
|
nvram_cmd = NVRAM_CMD_GO | NVRAM_CMD_DONE | NVRAM_CMD_WR |
|
||||||
|
NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_ERASE;
|
||||||
|
|
||||||
|
if (tg3_nvram_exec_cmd(tp, nvram_cmd))
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Issue another write enable to start the write. */
|
||||||
|
nvram_cmd = NVRAM_CMD_WREN | NVRAM_CMD_GO | NVRAM_CMD_DONE;
|
||||||
|
|
||||||
|
if (tg3_nvram_exec_cmd(tp, nvram_cmd))
|
||||||
|
break;
|
||||||
|
|
||||||
|
for (j = 0; j < pagesize; j += 4) {
|
||||||
|
__be32 data;
|
||||||
|
|
||||||
|
data = *((__be32 *) (tmp + j));
|
||||||
|
|
||||||
|
tw32(NVRAM_WRDATA, be32_to_cpu(data));
|
||||||
|
|
||||||
|
tw32(NVRAM_ADDR, phy_addr + j);
|
||||||
|
|
||||||
|
nvram_cmd = NVRAM_CMD_GO | NVRAM_CMD_DONE |
|
||||||
|
NVRAM_CMD_WR;
|
||||||
|
|
||||||
|
if (j == 0)
|
||||||
|
nvram_cmd |= NVRAM_CMD_FIRST;
|
||||||
|
else if (j == (pagesize - 4))
|
||||||
|
nvram_cmd |= NVRAM_CMD_LAST;
|
||||||
|
|
||||||
|
ret = tg3_nvram_exec_cmd(tp, nvram_cmd);
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
nvram_cmd = NVRAM_CMD_WRDI | NVRAM_CMD_GO | NVRAM_CMD_DONE;
|
||||||
|
tg3_nvram_exec_cmd(tp, nvram_cmd);
|
||||||
|
|
||||||
|
kfree(tmp);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* offset and length are dword aligned */
|
||||||
|
static int tg3_nvram_write_block_buffered(struct tg3 *tp, u32 offset, u32 len,
|
||||||
|
u8 *buf)
|
||||||
|
{
|
||||||
|
int i, ret = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i += 4, offset += 4) {
|
||||||
|
u32 page_off, phy_addr, nvram_cmd;
|
||||||
|
__be32 data;
|
||||||
|
|
||||||
|
memcpy(&data, buf + i, 4);
|
||||||
|
tw32(NVRAM_WRDATA, be32_to_cpu(data));
|
||||||
|
|
||||||
|
page_off = offset % tp->nvram_pagesize;
|
||||||
|
|
||||||
|
phy_addr = tg3_nvram_phys_addr(tp, offset);
|
||||||
|
|
||||||
|
tw32(NVRAM_ADDR, phy_addr);
|
||||||
|
|
||||||
|
nvram_cmd = NVRAM_CMD_GO | NVRAM_CMD_DONE | NVRAM_CMD_WR;
|
||||||
|
|
||||||
|
if (page_off == 0 || i == 0)
|
||||||
|
nvram_cmd |= NVRAM_CMD_FIRST;
|
||||||
|
if (page_off == (tp->nvram_pagesize - 4))
|
||||||
|
nvram_cmd |= NVRAM_CMD_LAST;
|
||||||
|
|
||||||
|
if (i == (len - 4))
|
||||||
|
nvram_cmd |= NVRAM_CMD_LAST;
|
||||||
|
|
||||||
|
if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752 &&
|
||||||
|
!tg3_flag(tp, 5755_PLUS) &&
|
||||||
|
(tp->nvram_jedecnum == JEDEC_ST) &&
|
||||||
|
(nvram_cmd & NVRAM_CMD_FIRST)) {
|
||||||
|
u32 cmd;
|
||||||
|
|
||||||
|
cmd = NVRAM_CMD_WREN | NVRAM_CMD_GO | NVRAM_CMD_DONE;
|
||||||
|
ret = tg3_nvram_exec_cmd(tp, cmd);
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!tg3_flag(tp, FLASH)) {
|
||||||
|
/* We always do complete word writes to eeprom. */
|
||||||
|
nvram_cmd |= (NVRAM_CMD_FIRST | NVRAM_CMD_LAST);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = tg3_nvram_exec_cmd(tp, nvram_cmd);
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* offset and length are dword aligned */
|
||||||
|
static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (tg3_flag(tp, EEPROM_WRITE_PROT)) {
|
||||||
|
tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl &
|
||||||
|
~GRC_LCLCTRL_GPIO_OUTPUT1);
|
||||||
|
udelay(40);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tg3_flag(tp, NVRAM)) {
|
||||||
|
ret = tg3_nvram_write_block_using_eeprom(tp, offset, len, buf);
|
||||||
|
} else {
|
||||||
|
u32 grc_mode;
|
||||||
|
|
||||||
|
ret = tg3_nvram_lock(tp);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
tg3_enable_nvram_access(tp);
|
||||||
|
if (tg3_flag(tp, 5750_PLUS) && !tg3_flag(tp, PROTECTED_NVRAM))
|
||||||
|
tw32(NVRAM_WRITE1, 0x406);
|
||||||
|
|
||||||
|
grc_mode = tr32(GRC_MODE);
|
||||||
|
tw32(GRC_MODE, grc_mode | GRC_MODE_NVRAM_WR_ENABLE);
|
||||||
|
|
||||||
|
if (tg3_flag(tp, NVRAM_BUFFERED) || !tg3_flag(tp, FLASH)) {
|
||||||
|
ret = tg3_nvram_write_block_buffered(tp, offset, len,
|
||||||
|
buf);
|
||||||
|
} else {
|
||||||
|
ret = tg3_nvram_write_block_unbuffered(tp, offset, len,
|
||||||
|
buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
grc_mode = tr32(GRC_MODE);
|
||||||
|
tw32(GRC_MODE, grc_mode & ~GRC_MODE_NVRAM_WR_ENABLE);
|
||||||
|
|
||||||
|
tg3_disable_nvram_access(tp);
|
||||||
|
tg3_nvram_unlock(tp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tg3_flag(tp, EEPROM_WRITE_PROT)) {
|
||||||
|
tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
|
||||||
|
udelay(40);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
#define RX_CPU_SCRATCH_BASE 0x30000
|
#define RX_CPU_SCRATCH_BASE 0x30000
|
||||||
#define RX_CPU_SCRATCH_SIZE 0x04000
|
#define RX_CPU_SCRATCH_SIZE 0x04000
|
||||||
#define TX_CPU_SCRATCH_BASE 0x34000
|
#define TX_CPU_SCRATCH_BASE 0x34000
|
||||||
@@ -10147,8 +10397,6 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf);
|
|
||||||
|
|
||||||
static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data)
|
static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data)
|
||||||
{
|
{
|
||||||
struct tg3 *tp = netdev_priv(dev);
|
struct tg3 *tp = netdev_priv(dev);
|
||||||
@@ -12745,254 +12993,6 @@ static void __devinit tg3_nvram_init(struct tg3 *tp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tg3_nvram_write_block_using_eeprom(struct tg3 *tp,
|
|
||||||
u32 offset, u32 len, u8 *buf)
|
|
||||||
{
|
|
||||||
int i, j, rc = 0;
|
|
||||||
u32 val;
|
|
||||||
|
|
||||||
for (i = 0; i < len; i += 4) {
|
|
||||||
u32 addr;
|
|
||||||
__be32 data;
|
|
||||||
|
|
||||||
addr = offset + i;
|
|
||||||
|
|
||||||
memcpy(&data, buf + i, 4);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The SEEPROM interface expects the data to always be opposite
|
|
||||||
* the native endian format. We accomplish this by reversing
|
|
||||||
* all the operations that would have been performed on the
|
|
||||||
* data from a call to tg3_nvram_read_be32().
|
|
||||||
*/
|
|
||||||
tw32(GRC_EEPROM_DATA, swab32(be32_to_cpu(data)));
|
|
||||||
|
|
||||||
val = tr32(GRC_EEPROM_ADDR);
|
|
||||||
tw32(GRC_EEPROM_ADDR, val | EEPROM_ADDR_COMPLETE);
|
|
||||||
|
|
||||||
val &= ~(EEPROM_ADDR_ADDR_MASK | EEPROM_ADDR_DEVID_MASK |
|
|
||||||
EEPROM_ADDR_READ);
|
|
||||||
tw32(GRC_EEPROM_ADDR, val |
|
|
||||||
(0 << EEPROM_ADDR_DEVID_SHIFT) |
|
|
||||||
(addr & EEPROM_ADDR_ADDR_MASK) |
|
|
||||||
EEPROM_ADDR_START |
|
|
||||||
EEPROM_ADDR_WRITE);
|
|
||||||
|
|
||||||
for (j = 0; j < 1000; j++) {
|
|
||||||
val = tr32(GRC_EEPROM_ADDR);
|
|
||||||
|
|
||||||
if (val & EEPROM_ADDR_COMPLETE)
|
|
||||||
break;
|
|
||||||
msleep(1);
|
|
||||||
}
|
|
||||||
if (!(val & EEPROM_ADDR_COMPLETE)) {
|
|
||||||
rc = -EBUSY;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* offset and length are dword aligned */
|
|
||||||
static int tg3_nvram_write_block_unbuffered(struct tg3 *tp, u32 offset, u32 len,
|
|
||||||
u8 *buf)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
u32 pagesize = tp->nvram_pagesize;
|
|
||||||
u32 pagemask = pagesize - 1;
|
|
||||||
u32 nvram_cmd;
|
|
||||||
u8 *tmp;
|
|
||||||
|
|
||||||
tmp = kmalloc(pagesize, GFP_KERNEL);
|
|
||||||
if (tmp == NULL)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
while (len) {
|
|
||||||
int j;
|
|
||||||
u32 phy_addr, page_off, size;
|
|
||||||
|
|
||||||
phy_addr = offset & ~pagemask;
|
|
||||||
|
|
||||||
for (j = 0; j < pagesize; j += 4) {
|
|
||||||
ret = tg3_nvram_read_be32(tp, phy_addr + j,
|
|
||||||
(__be32 *) (tmp + j));
|
|
||||||
if (ret)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (ret)
|
|
||||||
break;
|
|
||||||
|
|
||||||
page_off = offset & pagemask;
|
|
||||||
size = pagesize;
|
|
||||||
if (len < size)
|
|
||||||
size = len;
|
|
||||||
|
|
||||||
len -= size;
|
|
||||||
|
|
||||||
memcpy(tmp + page_off, buf, size);
|
|
||||||
|
|
||||||
offset = offset + (pagesize - page_off);
|
|
||||||
|
|
||||||
tg3_enable_nvram_access(tp);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Before we can erase the flash page, we need
|
|
||||||
* to issue a special "write enable" command.
|
|
||||||
*/
|
|
||||||
nvram_cmd = NVRAM_CMD_WREN | NVRAM_CMD_GO | NVRAM_CMD_DONE;
|
|
||||||
|
|
||||||
if (tg3_nvram_exec_cmd(tp, nvram_cmd))
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Erase the target page */
|
|
||||||
tw32(NVRAM_ADDR, phy_addr);
|
|
||||||
|
|
||||||
nvram_cmd = NVRAM_CMD_GO | NVRAM_CMD_DONE | NVRAM_CMD_WR |
|
|
||||||
NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_ERASE;
|
|
||||||
|
|
||||||
if (tg3_nvram_exec_cmd(tp, nvram_cmd))
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Issue another write enable to start the write. */
|
|
||||||
nvram_cmd = NVRAM_CMD_WREN | NVRAM_CMD_GO | NVRAM_CMD_DONE;
|
|
||||||
|
|
||||||
if (tg3_nvram_exec_cmd(tp, nvram_cmd))
|
|
||||||
break;
|
|
||||||
|
|
||||||
for (j = 0; j < pagesize; j += 4) {
|
|
||||||
__be32 data;
|
|
||||||
|
|
||||||
data = *((__be32 *) (tmp + j));
|
|
||||||
|
|
||||||
tw32(NVRAM_WRDATA, be32_to_cpu(data));
|
|
||||||
|
|
||||||
tw32(NVRAM_ADDR, phy_addr + j);
|
|
||||||
|
|
||||||
nvram_cmd = NVRAM_CMD_GO | NVRAM_CMD_DONE |
|
|
||||||
NVRAM_CMD_WR;
|
|
||||||
|
|
||||||
if (j == 0)
|
|
||||||
nvram_cmd |= NVRAM_CMD_FIRST;
|
|
||||||
else if (j == (pagesize - 4))
|
|
||||||
nvram_cmd |= NVRAM_CMD_LAST;
|
|
||||||
|
|
||||||
if ((ret = tg3_nvram_exec_cmd(tp, nvram_cmd)))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (ret)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
nvram_cmd = NVRAM_CMD_WRDI | NVRAM_CMD_GO | NVRAM_CMD_DONE;
|
|
||||||
tg3_nvram_exec_cmd(tp, nvram_cmd);
|
|
||||||
|
|
||||||
kfree(tmp);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* offset and length are dword aligned */
|
|
||||||
static int tg3_nvram_write_block_buffered(struct tg3 *tp, u32 offset, u32 len,
|
|
||||||
u8 *buf)
|
|
||||||
{
|
|
||||||
int i, ret = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < len; i += 4, offset += 4) {
|
|
||||||
u32 page_off, phy_addr, nvram_cmd;
|
|
||||||
__be32 data;
|
|
||||||
|
|
||||||
memcpy(&data, buf + i, 4);
|
|
||||||
tw32(NVRAM_WRDATA, be32_to_cpu(data));
|
|
||||||
|
|
||||||
page_off = offset % tp->nvram_pagesize;
|
|
||||||
|
|
||||||
phy_addr = tg3_nvram_phys_addr(tp, offset);
|
|
||||||
|
|
||||||
tw32(NVRAM_ADDR, phy_addr);
|
|
||||||
|
|
||||||
nvram_cmd = NVRAM_CMD_GO | NVRAM_CMD_DONE | NVRAM_CMD_WR;
|
|
||||||
|
|
||||||
if (page_off == 0 || i == 0)
|
|
||||||
nvram_cmd |= NVRAM_CMD_FIRST;
|
|
||||||
if (page_off == (tp->nvram_pagesize - 4))
|
|
||||||
nvram_cmd |= NVRAM_CMD_LAST;
|
|
||||||
|
|
||||||
if (i == (len - 4))
|
|
||||||
nvram_cmd |= NVRAM_CMD_LAST;
|
|
||||||
|
|
||||||
if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752 &&
|
|
||||||
!tg3_flag(tp, 5755_PLUS) &&
|
|
||||||
(tp->nvram_jedecnum == JEDEC_ST) &&
|
|
||||||
(nvram_cmd & NVRAM_CMD_FIRST)) {
|
|
||||||
|
|
||||||
if ((ret = tg3_nvram_exec_cmd(tp,
|
|
||||||
NVRAM_CMD_WREN | NVRAM_CMD_GO |
|
|
||||||
NVRAM_CMD_DONE)))
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!tg3_flag(tp, FLASH)) {
|
|
||||||
/* We always do complete word writes to eeprom. */
|
|
||||||
nvram_cmd |= (NVRAM_CMD_FIRST | NVRAM_CMD_LAST);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ret = tg3_nvram_exec_cmd(tp, nvram_cmd)))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* offset and length are dword aligned */
|
|
||||||
static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (tg3_flag(tp, EEPROM_WRITE_PROT)) {
|
|
||||||
tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl &
|
|
||||||
~GRC_LCLCTRL_GPIO_OUTPUT1);
|
|
||||||
udelay(40);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!tg3_flag(tp, NVRAM)) {
|
|
||||||
ret = tg3_nvram_write_block_using_eeprom(tp, offset, len, buf);
|
|
||||||
} else {
|
|
||||||
u32 grc_mode;
|
|
||||||
|
|
||||||
ret = tg3_nvram_lock(tp);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
tg3_enable_nvram_access(tp);
|
|
||||||
if (tg3_flag(tp, 5750_PLUS) && !tg3_flag(tp, PROTECTED_NVRAM))
|
|
||||||
tw32(NVRAM_WRITE1, 0x406);
|
|
||||||
|
|
||||||
grc_mode = tr32(GRC_MODE);
|
|
||||||
tw32(GRC_MODE, grc_mode | GRC_MODE_NVRAM_WR_ENABLE);
|
|
||||||
|
|
||||||
if (tg3_flag(tp, NVRAM_BUFFERED) || !tg3_flag(tp, FLASH)) {
|
|
||||||
ret = tg3_nvram_write_block_buffered(tp, offset, len,
|
|
||||||
buf);
|
|
||||||
} else {
|
|
||||||
ret = tg3_nvram_write_block_unbuffered(tp, offset, len,
|
|
||||||
buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
grc_mode = tr32(GRC_MODE);
|
|
||||||
tw32(GRC_MODE, grc_mode & ~GRC_MODE_NVRAM_WR_ENABLE);
|
|
||||||
|
|
||||||
tg3_disable_nvram_access(tp);
|
|
||||||
tg3_nvram_unlock(tp);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tg3_flag(tp, EEPROM_WRITE_PROT)) {
|
|
||||||
tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
|
|
||||||
udelay(40);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct subsys_tbl_ent {
|
struct subsys_tbl_ent {
|
||||||
u16 subsys_vendor, subsys_devid;
|
u16 subsys_vendor, subsys_devid;
|
||||||
u32 phy_id;
|
u32 phy_id;
|
||||||
|
Reference in New Issue
Block a user