Commit ad8d3948 authored by Eilon Greenstein's avatar Eilon Greenstein Committed by David S. Miller

bnx2x: New init infrastructure

This new initialization code supports the 57711 HW. It also supports
the emulation and FPGA for the 57711 and 57710 initializations values
(very small amount of code which is very helpful in the lab - less
than 30 lines).

The initialization is done via DMAE after the DMAE block is ready -
before it is ready, some of the initialization is done via PCI
configuration transactions (referred to as indirect write).  A mutex
to protect the DMAE from being overlapped was added.  There are few
new registers which needs to be initialized by SW - the full comment
for those registers is added to the register file.  A place holder for
the 57711 (referred to as E1H) microcode was added- the microcode
itself is too big and it is split over the following 4 patches
Signed-off-by: default avatarEilon Greenstein <eilong@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c18487ee
......@@ -559,23 +559,35 @@ struct bnx2x {
u32 chip_id;
/* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */
#define CHIP_ID(bp) (((bp)->chip_id) & 0xfffffff0)
#define CHIP_ID(bp) (bp->chip_id & 0xfffffff0)
#define CHIP_NUM(bp) (bp->chip_id >> 16)
#define CHIP_NUM_57710 0x164e
#define CHIP_NUM_57711 0x164f
#define CHIP_NUM_57711E 0x1650
#define CHIP_IS_E1(bp) (CHIP_NUM(bp) == CHIP_NUM_57710)
#define CHIP_IS_57711(bp) (CHIP_NUM(bp) == CHIP_NUM_57711)
#define CHIP_IS_57711E(bp) (CHIP_NUM(bp) == CHIP_NUM_57711E)
#define CHIP_IS_E1H(bp) (CHIP_IS_57711(bp) || \
CHIP_IS_57711E(bp))
#define IS_E1H_OFFSET CHIP_IS_E1H(bp)
#define CHIP_REV(bp) (bp->chip_id & 0x0000f000)
#define CHIP_REV_Ax 0x00000000
/* assume maximum 5 revisions */
#define CHIP_REV_IS_SLOW(bp) (CHIP_REV(bp) > 0x00005000)
/* Emul versions are A=>0xe, B=>0xc, C=>0xa, D=>8, E=>6 */
#define CHIP_REV_IS_EMUL(bp) ((CHIP_REV_IS_SLOW(bp)) && \
!(CHIP_REV(bp) & 0x00001000))
/* FPGA versions are A=>0xf, B=>0xd, C=>0xb, D=>9, E=>7 */
#define CHIP_REV_IS_FPGA(bp) ((CHIP_REV_IS_SLOW(bp)) && \
(CHIP_REV(bp) & 0x00001000))
#define CHIP_NUM(bp) (((bp)->chip_id) & 0xffff0000)
#define CHIP_TIME(bp) ((CHIP_REV_IS_EMUL(bp)) ? 2000 : \
((CHIP_REV_IS_FPGA(bp)) ? 200 : 1))
#define CHIP_REV(bp) (((bp)->chip_id) & 0x0000f000)
#define CHIP_REV_Ax 0x00000000
#define CHIP_REV_Bx 0x00001000
#define CHIP_REV_Cx 0x00002000
#define CHIP_REV_EMUL 0x0000e000
#define CHIP_REV_FPGA 0x0000f000
#define CHIP_REV_IS_SLOW(bp) ((CHIP_REV(bp) == CHIP_REV_EMUL) || \
(CHIP_REV(bp) == CHIP_REV_FPGA))
#define CHIP_REV_IS_EMUL(bp) (CHIP_REV(bp) == CHIP_REV_EMUL)
#define CHIP_REV_IS_FPGA(bp) (CHIP_REV(bp) == CHIP_REV_FPGA)
#define CHIP_METAL(bp) (((bp)->chip_id) & 0x00000ff0)
#define CHIP_BOND_ID(bp) (((bp)->chip_id) & 0x0000000f)
#define CHIP_METAL(bp) (bp->chip_id & 0x00000ff0)
#define CHIP_BOND_ID(bp) (bp->chip_id & 0x0000000f)
u16 fw_seq;
u16 fw_drv_pulse_wr_seq;
......@@ -678,6 +690,13 @@ struct bnx2x {
struct dmae_command dmae;
int executer_idx;
int dmae_ready;
/* used to synchronize dmae accesses */
struct mutex dmae_mutex;
struct dmae_command init_dmae;
u32 old_brb_discard;
struct bmac_stats old_bmac;
struct tstorm_per_client_stats old_tclient;
......@@ -774,12 +793,6 @@ int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode);
#define STROM_ASSERT_ARRAY_SIZE 50
#define MDIO_INDIRECT_REG_ADDR 0x1f
#define MDIO_SET_REG_BANK(bp, reg_bank) \
bnx2x_mdio22_write(bp, MDIO_INDIRECT_REG_ADDR, reg_bank)
#define MDIO_ACCESS_TIMEOUT 1000
/* must be used on a CID before placing it on a HW ring */
#define HW_CID(bp, x) (x | (bp->port << 23))
......@@ -818,6 +831,42 @@ int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode);
DPM_TRIGER_TYPE); \
} while (0)
/* DMAE command defines */
#define DMAE_CMD_SRC_PCI 0
#define DMAE_CMD_SRC_GRC DMAE_COMMAND_SRC
#define DMAE_CMD_DST_PCI (1 << DMAE_COMMAND_DST_SHIFT)
#define DMAE_CMD_DST_GRC (2 << DMAE_COMMAND_DST_SHIFT)
#define DMAE_CMD_C_DST_PCI 0
#define DMAE_CMD_C_DST_GRC (1 << DMAE_COMMAND_C_DST_SHIFT)
#define DMAE_CMD_C_ENABLE DMAE_COMMAND_C_TYPE_ENABLE
#define DMAE_CMD_ENDIANITY_NO_SWAP (0 << DMAE_COMMAND_ENDIANITY_SHIFT)
#define DMAE_CMD_ENDIANITY_B_SWAP (1 << DMAE_COMMAND_ENDIANITY_SHIFT)
#define DMAE_CMD_ENDIANITY_DW_SWAP (2 << DMAE_COMMAND_ENDIANITY_SHIFT)
#define DMAE_CMD_ENDIANITY_B_DW_SWAP (3 << DMAE_COMMAND_ENDIANITY_SHIFT)
#define DMAE_CMD_PORT_0 0
#define DMAE_CMD_PORT_1 DMAE_COMMAND_PORT
#define DMAE_CMD_SRC_RESET DMAE_COMMAND_SRC_RESET
#define DMAE_CMD_DST_RESET DMAE_COMMAND_DST_RESET
#define DMAE_CMD_E1HVN_SHIFT DMAE_COMMAND_E1HVN_SHIFT
#define DMAE_LEN32_RD_MAX 0x80
#define DMAE_LEN32_WR_MAX 0x400
#define DMAE_COMP_VAL 0xe0d0d0ae
#define MAX_DMAE_C_PER_PORT 8
#define INIT_DMAE_C(bp) (BP_PORT(bp)*MAX_DMAE_C_PER_PORT + \
BP_E1HVN(bp))
#define PMF_DMAE_C(bp) (BP_PORT(bp)*MAX_DMAE_C_PER_PORT + \
E1HVN_MAX)
/* PCIE link and speed */
#define PCICFG_LINK_WIDTH 0x1f00000
#define PCICFG_LINK_WIDTH_SHIFT 20
......
......@@ -522,8 +522,21 @@ struct dev_info { /* size */
#define FUNC_0 0
#define FUNC_1 1
#define FUNC_2 2
#define FUNC_3 3
#define FUNC_4 4
#define FUNC_5 5
#define FUNC_6 6
#define FUNC_7 7
#define E1_FUNC_MAX 2
#define FUNC_MAX E1_FUNC_MAX
#define E1H_FUNC_MAX 8
#define VN_0 0
#define VN_1 1
#define VN_2 2
#define VN_3 3
#define E1VN_MAX 1
#define E1HVN_MAX 4
/* This value (in milliseconds) determines the frequency of the driver
......@@ -747,7 +760,11 @@ struct shmem_region { /* SharedMem Offset (size) */
struct mgmtfw_state mgmtfw_state; /* 0x4ac (0x1b8) */
struct drv_port_mb port_mb[PORT_MAX]; /* 0x664 (16*2=0x20) */
struct drv_func_mb func_mb[FUNC_MAX]; /* 0x684 (44*2=0x58) */
#if defined(b710)
struct drv_func_mb func_mb[E1_FUNC_MAX]; /* 0x684 (44*2=0x58) */
#else
struct drv_func_mb func_mb[E1H_FUNC_MAX];
#endif
}; /* 0x6dc */
......@@ -901,8 +918,10 @@ struct dmae_command {
#define DMAE_COMMAND_SRC_RESET_SHIFT 13
#define DMAE_COMMAND_DST_RESET (0x1<<14)
#define DMAE_COMMAND_DST_RESET_SHIFT 14
#define DMAE_COMMAND_RESERVED0 (0x1FFFF<<15)
#define DMAE_COMMAND_RESERVED0_SHIFT 15
#define DMAE_COMMAND_E1HVN (0x3<<15)
#define DMAE_COMMAND_E1HVN_SHIFT 15
#define DMAE_COMMAND_RESERVED0 (0x7FFF<<17)
#define DMAE_COMMAND_RESERVED0_SHIFT 17
u32 src_addr_lo;
u32 src_addr_hi;
u32 dst_addr_lo;
......
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -137,7 +137,6 @@ static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val)
PCICFG_VENDOR_ID_OFFSET);
}
#ifdef BNX2X_IND_RD
static u32 bnx2x_reg_rd_ind(struct bnx2x *bp, u32 addr)
{
u32 val;
......@@ -149,7 +148,6 @@ static u32 bnx2x_reg_rd_ind(struct bnx2x *bp, u32 addr)
return val;
}
#endif
static const u32 dmae_reg_go_c[] = {
DMAE_REG_GO_C0, DMAE_REG_GO_C1, DMAE_REG_GO_C2, DMAE_REG_GO_C3,
......@@ -169,19 +167,29 @@ static void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae,
for (i = 0; i < (sizeof(struct dmae_command)/4); i++) {
REG_WR(bp, cmd_offset + i*4, *(((u32 *)dmae) + i));
/* DP(NETIF_MSG_DMAE, "DMAE cmd[%d].%d (0x%08x) : 0x%08x\n",
idx, i, cmd_offset + i*4, *(((u32 *)dmae) + i)); */
DP(BNX2X_MSG_OFF, "DMAE cmd[%d].%d (0x%08x) : 0x%08x\n",
idx, i, cmd_offset + i*4, *(((u32 *)dmae) + i));
}
REG_WR(bp, dmae_reg_go_c[idx], 1);
}
void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr,
u32 dst_addr, u32 len32)
void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
u32 len32)
{
struct dmae_command *dmae = &bp->dmae;
int port = bp->port;
struct dmae_command *dmae = &bp->init_dmae;
u32 *wb_comp = bnx2x_sp(bp, wb_comp);
int timeout = 200;
int cnt = 200;
if (!bp->dmae_ready) {
u32 *data = bnx2x_sp(bp, wb_data[0]);
DP(BNX2X_MSG_OFF, "DMAE is not ready (dst_addr %08x len32 %d)"
" using indirect\n", dst_addr, len32);
bnx2x_init_ind_wr(bp, dst_addr, data, len32);
return;
}
mutex_lock(&bp->dmae_mutex);
memset(dmae, 0, sizeof(struct dmae_command));
......@@ -193,7 +201,7 @@ void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr,
#else
DMAE_CMD_ENDIANITY_DW_SWAP |
#endif
(port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0));
(bp->port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0));
dmae->src_addr_lo = U64_LO(dma_addr);
dmae->src_addr_hi = U64_HI(dma_addr);
dmae->dst_addr_lo = dst_addr >> 2;
......@@ -201,48 +209,62 @@ void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr,
dmae->len = len32;
dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp));
dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp));
dmae->comp_val = BNX2X_WB_COMP_VAL;
dmae->comp_val = DMAE_COMP_VAL;
/*
DP(NETIF_MSG_DMAE, "dmae: opcode 0x%08x\n"
DP(BNX2X_MSG_OFF, "dmae: opcode 0x%08x\n"
DP_LEVEL "src_addr [%x:%08x] len [%d *4] "
"dst_addr [%x:%08x (%08x)]\n"
DP_LEVEL "comp_addr [%x:%08x] comp_val 0x%08x\n",
dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo,
dmae->len, dmae->dst_addr_hi, dmae->dst_addr_lo, dst_addr,
dmae->comp_addr_hi, dmae->comp_addr_lo, dmae->comp_val);
*/
/*
DP(NETIF_MSG_DMAE, "data [0x%08x 0x%08x 0x%08x 0x%08x]\n",
DP(BNX2X_MSG_OFF, "data [0x%08x 0x%08x 0x%08x 0x%08x]\n",
bp->slowpath->wb_data[0], bp->slowpath->wb_data[1],
bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]);
*/
*wb_comp = 0;
bnx2x_post_dmae(bp, dmae, port * 8);
bnx2x_post_dmae(bp, dmae, (bp->port)*MAX_DMAE_C_PER_PORT);
udelay(5);
/* adjust timeout for emulation/FPGA */
while (*wb_comp != DMAE_COMP_VAL) {
DP(BNX2X_MSG_OFF, "wb_comp 0x%08x\n", *wb_comp);
/* adjust delay for emulation/FPGA */
if (CHIP_REV_IS_SLOW(bp))
timeout *= 100;
while (*wb_comp != BNX2X_WB_COMP_VAL) {
/* DP(NETIF_MSG_DMAE, "wb_comp 0x%08x\n", *wb_comp); */
msleep(100);
else
udelay(5);
if (!timeout) {
if (!cnt) {
BNX2X_ERR("dmae timeout!\n");
break;
}
timeout--;
cnt--;
}
mutex_unlock(&bp->dmae_mutex);
}
void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
{
struct dmae_command *dmae = &bp->dmae;
int port = bp->port;
struct dmae_command *dmae = &bp->init_dmae;
u32 *wb_comp = bnx2x_sp(bp, wb_comp);
int timeout = 200;
int cnt = 200;
if (!bp->dmae_ready) {
u32 *data = bnx2x_sp(bp, wb_data[0]);
int i;
DP(BNX2X_MSG_OFF, "DMAE is not ready (src_addr %08x len32 %d)"
" using indirect\n", src_addr, len32);
for (i = 0; i < len32; i++)
data[i] = bnx2x_reg_rd_ind(bp, src_addr + i*4);
return;
}
mutex_lock(&bp->dmae_mutex);
memset(bnx2x_sp(bp, wb_data[0]), 0, sizeof(u32) * 4);
memset(dmae, 0, sizeof(struct dmae_command));
......@@ -255,7 +277,7 @@ void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
#else
DMAE_CMD_ENDIANITY_DW_SWAP |
#endif
(port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0));
(bp->port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0));
dmae->src_addr_lo = src_addr >> 2;
dmae->src_addr_hi = 0;
dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_data));
......@@ -263,38 +285,64 @@ void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
dmae->len = len32;
dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp));
dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp));
dmae->comp_val = BNX2X_WB_COMP_VAL;
dmae->comp_val = DMAE_COMP_VAL;
/*
DP(NETIF_MSG_DMAE, "dmae: opcode 0x%08x\n"
DP(BNX2X_MSG_OFF, "dmae: opcode 0x%08x\n"
DP_LEVEL "src_addr [%x:%08x] len [%d *4] "
"dst_addr [%x:%08x (%08x)]\n"
DP_LEVEL "comp_addr [%x:%08x] comp_val 0x%08x\n",
dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo,
dmae->len, dmae->dst_addr_hi, dmae->dst_addr_lo, src_addr,
dmae->comp_addr_hi, dmae->comp_addr_lo, dmae->comp_val);
*/
*wb_comp = 0;
bnx2x_post_dmae(bp, dmae, port * 8);
bnx2x_post_dmae(bp, dmae, (bp->port)*MAX_DMAE_C_PER_PORT);
udelay(5);
while (*wb_comp != BNX2X_WB_COMP_VAL) {
while (*wb_comp != DMAE_COMP_VAL) {
/* adjust delay for emulation/FPGA */
if (CHIP_REV_IS_SLOW(bp))
msleep(100);
else
udelay(5);
if (!timeout) {
if (!cnt) {
BNX2X_ERR("dmae timeout!\n");
break;
}
timeout--;
cnt--;
}
/*
DP(NETIF_MSG_DMAE, "data [0x%08x 0x%08x 0x%08x 0x%08x]\n",
DP(BNX2X_MSG_OFF, "data [0x%08x 0x%08x 0x%08x 0x%08x]\n",
bp->slowpath->wb_data[0], bp->slowpath->wb_data[1],
bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]);
*/
mutex_unlock(&bp->dmae_mutex);
}
/* used only for slowpath so not inlined */
static void bnx2x_wb_wr(struct bnx2x *bp, int reg, u32 val_hi, u32 val_lo)
{
u32 wb_write[2];
wb_write[0] = val_hi;
wb_write[1] = val_lo;
REG_WR_DMAE(bp, reg, wb_write, 2);
}
#ifdef USE_WB_RD
static u64 bnx2x_wb_rd(struct bnx2x *bp, int reg)
{
u32 wb_data[2];
REG_RD_DMAE(bp, reg, wb_data, 2);
return HILO_U64(wb_data[0], wb_data[1]);
}
#endif
static int bnx2x_mc_assert(struct bnx2x *bp)
{
int i, j, rc = 0;
......@@ -3438,17 +3486,12 @@ static int bnx2x_int_mem_test(struct bnx2x *bp)
int count, i;
u32 val = 0;
switch (CHIP_REV(bp)) {
case CHIP_REV_EMUL:
factor = 200;
break;
case CHIP_REV_FPGA:
if (CHIP_REV_IS_FPGA(bp))
factor = 120;
break;
default:
else if (CHIP_REV_IS_EMUL(bp))
factor = 200;
else
factor = 1;
break;
}
DP(NETIF_MSG_HW, "start part1\n");
......@@ -3777,10 +3820,14 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode)
bnx2x_init_block(bp, USDM_COMMON_START, USDM_COMMON_END);
bnx2x_init_block(bp, XSDM_COMMON_START, XSDM_COMMON_END);
bnx2x_init_fill(bp, TSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE);
bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE);
bnx2x_init_fill(bp, XSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE);
bnx2x_init_fill(bp, USTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE);
bnx2x_init_fill(bp, TSTORM_INTMEM_ADDR, 0,
STORM_INTMEM_SIZE_E1);
bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR, 0,
STORM_INTMEM_SIZE_E1);
bnx2x_init_fill(bp, XSTORM_INTMEM_ADDR, 0,
STORM_INTMEM_SIZE_E1);
bnx2x_init_fill(bp, USTORM_INTMEM_ADDR, 0,
STORM_INTMEM_SIZE_E1);
bnx2x_init_block(bp, TSEM_COMMON_START, TSEM_COMMON_END);
bnx2x_init_block(bp, USEM_COMMON_START, USEM_COMMON_END);
......@@ -3990,8 +4037,7 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode)
#endif
/* Port DQ comes here */
/* Port BRB1 comes here */
bnx2x_init_block(bp, func ? PRS_PORT1_START : PRS_PORT0_START,
func ? PRS_PORT1_END : PRS_PORT0_END);
/* Port PRS comes here */
/* Port TSDM comes here */
/* Port CSDM comes here */
/* Port USDM comes here */
......@@ -7264,12 +7310,6 @@ static int __devinit bnx2x_init_board(struct pci_dev *pdev,
bnx2x_get_hwinfo(bp);
if (CHIP_REV(bp) == CHIP_REV_FPGA) {
printk(KERN_ERR PFX "FPGA detected. MCP disabled,"
" will only init first device\n");
onefunc = 1;
nomcp = 1;
}
if (nomcp) {
printk(KERN_ERR PFX "MCP disabled, will only"
......
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