mirror of https://gitee.com/openkylin/linux.git
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:
parent
ccd5ba9db5
commit
dbe9b92a60
|
@ -2978,6 +2978,256 @@ static int tg3_nvram_read_be32(struct tg3 *tp, u32 offset, __be32 *val)
|
|||
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_SIZE 0x04000
|
||||
#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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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 {
|
||||
u16 subsys_vendor, subsys_devid;
|
||||
u32 phy_id;
|
||||
|
|
Loading…
Reference in New Issue