Commit 997b4f13 authored by Matt Carlson's avatar Matt Carlson Committed by David S. Miller

tg3: Eliminate tg3_halt_cpu() prototype

This patch moves the implementatino of tg3_halt_cpu() earlier in the
file to eliminate its prototype.
Signed-off-by: default avatarMatt Carlson <mcarlson@broadcom.com>
Reviewed-by: default avatarBenjamin Li <benli@broadcom.com>
Reviewed-by: default avatarMichael Chan <mchan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent fd6d3f0e
...@@ -2999,6 +2999,228 @@ static int tg3_nvram_read_be32(struct tg3 *tp, u32 offset, __be32 *val) ...@@ -2999,6 +2999,228 @@ static int tg3_nvram_read_be32(struct tg3 *tp, u32 offset, __be32 *val)
return res; return res;
} }
#define RX_CPU_SCRATCH_BASE 0x30000
#define RX_CPU_SCRATCH_SIZE 0x04000
#define TX_CPU_SCRATCH_BASE 0x34000
#define TX_CPU_SCRATCH_SIZE 0x04000
/* tp->lock is held. */
static int tg3_halt_cpu(struct tg3 *tp, u32 offset)
{
int i;
BUG_ON(offset == TX_CPU_BASE && tg3_flag(tp, 5705_PLUS));
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
u32 val = tr32(GRC_VCPU_EXT_CTRL);
tw32(GRC_VCPU_EXT_CTRL, val | GRC_VCPU_EXT_CTRL_HALT_CPU);
return 0;
}
if (offset == RX_CPU_BASE) {
for (i = 0; i < 10000; i++) {
tw32(offset + CPU_STATE, 0xffffffff);
tw32(offset + CPU_MODE, CPU_MODE_HALT);
if (tr32(offset + CPU_MODE) & CPU_MODE_HALT)
break;
}
tw32(offset + CPU_STATE, 0xffffffff);
tw32_f(offset + CPU_MODE, CPU_MODE_HALT);
udelay(10);
} else {
for (i = 0; i < 10000; i++) {
tw32(offset + CPU_STATE, 0xffffffff);
tw32(offset + CPU_MODE, CPU_MODE_HALT);
if (tr32(offset + CPU_MODE) & CPU_MODE_HALT)
break;
}
}
if (i >= 10000) {
netdev_err(tp->dev, "%s timed out, %s CPU\n",
__func__, offset == RX_CPU_BASE ? "RX" : "TX");
return -ENODEV;
}
/* Clear firmware's nvram arbitration. */
if (tg3_flag(tp, NVRAM))
tw32(NVRAM_SWARB, SWARB_REQ_CLR0);
return 0;
}
struct fw_info {
unsigned int fw_base;
unsigned int fw_len;
const __be32 *fw_data;
};
/* tp->lock is held. */
static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base,
u32 cpu_scratch_base, int cpu_scratch_size,
struct fw_info *info)
{
int err, lock_err, i;
void (*write_op)(struct tg3 *, u32, u32);
if (cpu_base == TX_CPU_BASE && tg3_flag(tp, 5705_PLUS)) {
netdev_err(tp->dev,
"%s: Trying to load TX cpu firmware which is 5705\n",
__func__);
return -EINVAL;
}
if (tg3_flag(tp, 5705_PLUS))
write_op = tg3_write_mem;
else
write_op = tg3_write_indirect_reg32;
/* It is possible that bootcode is still loading at this point.
* Get the nvram lock first before halting the cpu.
*/
lock_err = tg3_nvram_lock(tp);
err = tg3_halt_cpu(tp, cpu_base);
if (!lock_err)
tg3_nvram_unlock(tp);
if (err)
goto out;
for (i = 0; i < cpu_scratch_size; i += sizeof(u32))
write_op(tp, cpu_scratch_base + i, 0);
tw32(cpu_base + CPU_STATE, 0xffffffff);
tw32(cpu_base + CPU_MODE, tr32(cpu_base+CPU_MODE)|CPU_MODE_HALT);
for (i = 0; i < (info->fw_len / sizeof(u32)); i++)
write_op(tp, (cpu_scratch_base +
(info->fw_base & 0xffff) +
(i * sizeof(u32))),
be32_to_cpu(info->fw_data[i]));
err = 0;
out:
return err;
}
/* tp->lock is held. */
static int tg3_load_5701_a0_firmware_fix(struct tg3 *tp)
{
struct fw_info info;
const __be32 *fw_data;
int err, i;
fw_data = (void *)tp->fw->data;
/* Firmware blob starts with version numbers, followed by
start address and length. We are setting complete length.
length = end_address_of_bss - start_address_of_text.
Remainder is the blob to be loaded contiguously
from start address. */
info.fw_base = be32_to_cpu(fw_data[1]);
info.fw_len = tp->fw->size - 12;
info.fw_data = &fw_data[3];
err = tg3_load_firmware_cpu(tp, RX_CPU_BASE,
RX_CPU_SCRATCH_BASE, RX_CPU_SCRATCH_SIZE,
&info);
if (err)
return err;
err = tg3_load_firmware_cpu(tp, TX_CPU_BASE,
TX_CPU_SCRATCH_BASE, TX_CPU_SCRATCH_SIZE,
&info);
if (err)
return err;
/* Now startup only the RX cpu. */
tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff);
tw32_f(RX_CPU_BASE + CPU_PC, info.fw_base);
for (i = 0; i < 5; i++) {
if (tr32(RX_CPU_BASE + CPU_PC) == info.fw_base)
break;
tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff);
tw32(RX_CPU_BASE + CPU_MODE, CPU_MODE_HALT);
tw32_f(RX_CPU_BASE + CPU_PC, info.fw_base);
udelay(1000);
}
if (i >= 5) {
netdev_err(tp->dev, "%s fails to set RX CPU PC, is %08x "
"should be %08x\n", __func__,
tr32(RX_CPU_BASE + CPU_PC), info.fw_base);
return -ENODEV;
}
tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff);
tw32_f(RX_CPU_BASE + CPU_MODE, 0x00000000);
return 0;
}
/* tp->lock is held. */
static int tg3_load_tso_firmware(struct tg3 *tp)
{
struct fw_info info;
const __be32 *fw_data;
unsigned long cpu_base, cpu_scratch_base, cpu_scratch_size;
int err, i;
if (tg3_flag(tp, HW_TSO_1) ||
tg3_flag(tp, HW_TSO_2) ||
tg3_flag(tp, HW_TSO_3))
return 0;
fw_data = (void *)tp->fw->data;
/* Firmware blob starts with version numbers, followed by
start address and length. We are setting complete length.
length = end_address_of_bss - start_address_of_text.
Remainder is the blob to be loaded contiguously
from start address. */
info.fw_base = be32_to_cpu(fw_data[1]);
cpu_scratch_size = tp->fw_len;
info.fw_len = tp->fw->size - 12;
info.fw_data = &fw_data[3];
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
cpu_base = RX_CPU_BASE;
cpu_scratch_base = NIC_SRAM_MBUF_POOL_BASE5705;
} else {
cpu_base = TX_CPU_BASE;
cpu_scratch_base = TX_CPU_SCRATCH_BASE;
cpu_scratch_size = TX_CPU_SCRATCH_SIZE;
}
err = tg3_load_firmware_cpu(tp, cpu_base,
cpu_scratch_base, cpu_scratch_size,
&info);
if (err)
return err;
/* Now startup the cpu. */
tw32(cpu_base + CPU_STATE, 0xffffffff);
tw32_f(cpu_base + CPU_PC, info.fw_base);
for (i = 0; i < 5; i++) {
if (tr32(cpu_base + CPU_PC) == info.fw_base)
break;
tw32(cpu_base + CPU_STATE, 0xffffffff);
tw32(cpu_base + CPU_MODE, CPU_MODE_HALT);
tw32_f(cpu_base + CPU_PC, info.fw_base);
udelay(1000);
}
if (i >= 5) {
netdev_err(tp->dev,
"%s fails to set CPU PC, is %08x should be %08x\n",
__func__, tr32(cpu_base + CPU_PC), info.fw_base);
return -ENODEV;
}
tw32(cpu_base + CPU_STATE, 0xffffffff);
tw32_f(cpu_base + CPU_MODE, 0x00000000);
return 0;
}
/* tp->lock is held. */ /* tp->lock is held. */
static void __tg3_set_mac_addr(struct tg3 *tp, int skip_mac_1) static void __tg3_set_mac_addr(struct tg3 *tp, int skip_mac_1)
{ {
...@@ -7707,227 +7929,6 @@ static int tg3_halt(struct tg3 *tp, int kind, int silent) ...@@ -7707,227 +7929,6 @@ static int tg3_halt(struct tg3 *tp, int kind, int silent)
return 0; return 0;
} }
#define RX_CPU_SCRATCH_BASE 0x30000
#define RX_CPU_SCRATCH_SIZE 0x04000
#define TX_CPU_SCRATCH_BASE 0x34000
#define TX_CPU_SCRATCH_SIZE 0x04000
/* tp->lock is held. */
static int tg3_halt_cpu(struct tg3 *tp, u32 offset)
{
int i;
BUG_ON(offset == TX_CPU_BASE && tg3_flag(tp, 5705_PLUS));
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
u32 val = tr32(GRC_VCPU_EXT_CTRL);
tw32(GRC_VCPU_EXT_CTRL, val | GRC_VCPU_EXT_CTRL_HALT_CPU);
return 0;
}
if (offset == RX_CPU_BASE) {
for (i = 0; i < 10000; i++) {
tw32(offset + CPU_STATE, 0xffffffff);
tw32(offset + CPU_MODE, CPU_MODE_HALT);
if (tr32(offset + CPU_MODE) & CPU_MODE_HALT)
break;
}
tw32(offset + CPU_STATE, 0xffffffff);
tw32_f(offset + CPU_MODE, CPU_MODE_HALT);
udelay(10);
} else {
for (i = 0; i < 10000; i++) {
tw32(offset + CPU_STATE, 0xffffffff);
tw32(offset + CPU_MODE, CPU_MODE_HALT);
if (tr32(offset + CPU_MODE) & CPU_MODE_HALT)
break;
}
}
if (i >= 10000) {
netdev_err(tp->dev, "%s timed out, %s CPU\n",
__func__, offset == RX_CPU_BASE ? "RX" : "TX");
return -ENODEV;
}
/* Clear firmware's nvram arbitration. */
if (tg3_flag(tp, NVRAM))
tw32(NVRAM_SWARB, SWARB_REQ_CLR0);
return 0;
}
struct fw_info {
unsigned int fw_base;
unsigned int fw_len;
const __be32 *fw_data;
};
/* tp->lock is held. */
static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_base,
int cpu_scratch_size, struct fw_info *info)
{
int err, lock_err, i;
void (*write_op)(struct tg3 *, u32, u32);
if (cpu_base == TX_CPU_BASE && tg3_flag(tp, 5705_PLUS)) {
netdev_err(tp->dev,
"%s: Trying to load TX cpu firmware which is 5705\n",
__func__);
return -EINVAL;
}
if (tg3_flag(tp, 5705_PLUS))
write_op = tg3_write_mem;
else
write_op = tg3_write_indirect_reg32;
/* It is possible that bootcode is still loading at this point.
* Get the nvram lock first before halting the cpu.
*/
lock_err = tg3_nvram_lock(tp);
err = tg3_halt_cpu(tp, cpu_base);
if (!lock_err)
tg3_nvram_unlock(tp);
if (err)
goto out;
for (i = 0; i < cpu_scratch_size; i += sizeof(u32))
write_op(tp, cpu_scratch_base + i, 0);
tw32(cpu_base + CPU_STATE, 0xffffffff);
tw32(cpu_base + CPU_MODE, tr32(cpu_base+CPU_MODE)|CPU_MODE_HALT);
for (i = 0; i < (info->fw_len / sizeof(u32)); i++)
write_op(tp, (cpu_scratch_base +
(info->fw_base & 0xffff) +
(i * sizeof(u32))),
be32_to_cpu(info->fw_data[i]));
err = 0;
out:
return err;
}
/* tp->lock is held. */
static int tg3_load_5701_a0_firmware_fix(struct tg3 *tp)
{
struct fw_info info;
const __be32 *fw_data;
int err, i;
fw_data = (void *)tp->fw->data;
/* Firmware blob starts with version numbers, followed by
start address and length. We are setting complete length.
length = end_address_of_bss - start_address_of_text.
Remainder is the blob to be loaded contiguously
from start address. */
info.fw_base = be32_to_cpu(fw_data[1]);
info.fw_len = tp->fw->size - 12;
info.fw_data = &fw_data[3];
err = tg3_load_firmware_cpu(tp, RX_CPU_BASE,
RX_CPU_SCRATCH_BASE, RX_CPU_SCRATCH_SIZE,
&info);
if (err)
return err;
err = tg3_load_firmware_cpu(tp, TX_CPU_BASE,
TX_CPU_SCRATCH_BASE, TX_CPU_SCRATCH_SIZE,
&info);
if (err)
return err;
/* Now startup only the RX cpu. */
tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff);
tw32_f(RX_CPU_BASE + CPU_PC, info.fw_base);
for (i = 0; i < 5; i++) {
if (tr32(RX_CPU_BASE + CPU_PC) == info.fw_base)
break;
tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff);
tw32(RX_CPU_BASE + CPU_MODE, CPU_MODE_HALT);
tw32_f(RX_CPU_BASE + CPU_PC, info.fw_base);
udelay(1000);
}
if (i >= 5) {
netdev_err(tp->dev, "%s fails to set RX CPU PC, is %08x "
"should be %08x\n", __func__,
tr32(RX_CPU_BASE + CPU_PC), info.fw_base);
return -ENODEV;
}
tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff);
tw32_f(RX_CPU_BASE + CPU_MODE, 0x00000000);
return 0;
}
/* tp->lock is held. */
static int tg3_load_tso_firmware(struct tg3 *tp)
{
struct fw_info info;
const __be32 *fw_data;
unsigned long cpu_base, cpu_scratch_base, cpu_scratch_size;
int err, i;
if (tg3_flag(tp, HW_TSO_1) ||
tg3_flag(tp, HW_TSO_2) ||
tg3_flag(tp, HW_TSO_3))
return 0;
fw_data = (void *)tp->fw->data;
/* Firmware blob starts with version numbers, followed by
start address and length. We are setting complete length.
length = end_address_of_bss - start_address_of_text.
Remainder is the blob to be loaded contiguously
from start address. */
info.fw_base = be32_to_cpu(fw_data[1]);
cpu_scratch_size = tp->fw_len;
info.fw_len = tp->fw->size - 12;
info.fw_data = &fw_data[3];
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
cpu_base = RX_CPU_BASE;
cpu_scratch_base = NIC_SRAM_MBUF_POOL_BASE5705;
} else {
cpu_base = TX_CPU_BASE;
cpu_scratch_base = TX_CPU_SCRATCH_BASE;
cpu_scratch_size = TX_CPU_SCRATCH_SIZE;
}
err = tg3_load_firmware_cpu(tp, cpu_base,
cpu_scratch_base, cpu_scratch_size,
&info);
if (err)
return err;
/* Now startup the cpu. */
tw32(cpu_base + CPU_STATE, 0xffffffff);
tw32_f(cpu_base + CPU_PC, info.fw_base);
for (i = 0; i < 5; i++) {
if (tr32(cpu_base + CPU_PC) == info.fw_base)
break;
tw32(cpu_base + CPU_STATE, 0xffffffff);
tw32(cpu_base + CPU_MODE, CPU_MODE_HALT);
tw32_f(cpu_base + CPU_PC, info.fw_base);
udelay(1000);
}
if (i >= 5) {
netdev_err(tp->dev,
"%s fails to set CPU PC, is %08x should be %08x\n",
__func__, tr32(cpu_base + CPU_PC), info.fw_base);
return -ENODEV;
}
tw32(cpu_base + CPU_STATE, 0xffffffff);
tw32_f(cpu_base + CPU_MODE, 0x00000000);
return 0;
}
static int tg3_set_mac_addr(struct net_device *dev, void *p) static int tg3_set_mac_addr(struct net_device *dev, void *p)
{ {
struct tg3 *tp = netdev_priv(dev); struct tg3 *tp = netdev_priv(dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment