Yuval Mintz says:

====================
bnx2x: Bug fixes patch series

This patch series contains fixes for various flows - several SR-IOV issues
are fixed, ethtool callbacks (coalescing and register dump) are corrected,
null pointer dereference on error flows is prevented, etc.

Changes from V1
---------------
 - Patch 2  "bnx2x: Prevent an illegal pointer dereference during panic"
   is revised, with improved handling of edge cases.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2013-10-21 18:31:53 -04:00
Родитель 49595b7b21 edd3147601
Коммит 4440c6f7d5
7 изменённых файлов: 268 добавлений и 246 удалений

Просмотреть файл

@ -1197,8 +1197,9 @@ union cdu_context {
/* TM (timers) host DB constants */
#define TM_ILT_PAGE_SZ_HW 0
#define TM_ILT_PAGE_SZ (4096 << TM_ILT_PAGE_SZ_HW) /* 4K */
/* #define TM_CONN_NUM (CNIC_STARTING_CID+CNIC_ISCSI_CXT_MAX) */
#define TM_CONN_NUM 1024
#define TM_CONN_NUM (BNX2X_FIRST_VF_CID + \
BNX2X_VF_CIDS + \
CNIC_ISCSI_CID_MAX)
#define TM_ILT_SZ (8 * TM_CONN_NUM)
#define TM_ILT_LINES DIV_ROUND_UP(TM_ILT_SZ, TM_ILT_PAGE_SZ)
@ -1527,7 +1528,6 @@ struct bnx2x {
#define PCI_32BIT_FLAG (1 << 1)
#define ONE_PORT_FLAG (1 << 2)
#define NO_WOL_FLAG (1 << 3)
#define USING_DAC_FLAG (1 << 4)
#define USING_MSIX_FLAG (1 << 5)
#define USING_MSI_FLAG (1 << 6)
#define DISABLE_MSI_FLAG (1 << 7)
@ -1621,7 +1621,7 @@ struct bnx2x {
u16 rx_ticks_int;
u16 rx_ticks;
/* Maximal coalescing timeout in us */
#define BNX2X_MAX_COALESCE_TOUT (0xf0*12)
#define BNX2X_MAX_COALESCE_TOUT (0xff*BNX2X_BTR)
u32 lin_cnt;
@ -2072,7 +2072,8 @@ u32 bnx2x_dmae_opcode(struct bnx2x *bp, u8 src_type, u8 dst_type,
void bnx2x_prep_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae,
u8 src_type, u8 dst_type);
int bnx2x_issue_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae);
int bnx2x_issue_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae,
u32 *comp);
/* FLR related routines */
u32 bnx2x_flr_clnup_poll_count(struct bnx2x *bp);
@ -2498,4 +2499,8 @@ enum bnx2x_pci_bus_speed {
};
void bnx2x_set_local_cmng(struct bnx2x *bp);
#define MCPR_SCRATCH_BASE(bp) \
(CHIP_IS_E1x(bp) ? MCP_REG_MCPR_SCRATCH : MCP_A_REG_MCPR_SCRATCH)
#endif /* bnx2x.h */

Просмотреть файл

@ -891,17 +891,8 @@ static void bnx2x_get_regs(struct net_device *dev,
* will re-enable parity attentions right after the dump.
*/
/* Disable parity on path 0 */
bnx2x_pretend_func(bp, 0);
bnx2x_disable_blocks_parity(bp);
/* Disable parity on path 1 */
bnx2x_pretend_func(bp, 1);
bnx2x_disable_blocks_parity(bp);
/* Return to current function */
bnx2x_pretend_func(bp, BP_ABS_FUNC(bp));
dump_hdr.header_size = (sizeof(struct dump_header) / 4) - 1;
dump_hdr.preset = DUMP_ALL_PRESETS;
dump_hdr.version = BNX2X_DUMP_VERSION;
@ -928,18 +919,9 @@ static void bnx2x_get_regs(struct net_device *dev,
/* Actually read the registers */
__bnx2x_get_regs(bp, p);
/* Re-enable parity attentions on path 0 */
bnx2x_pretend_func(bp, 0);
/* Re-enable parity attentions */
bnx2x_clear_blocks_parity(bp);
bnx2x_enable_blocks_parity(bp);
/* Re-enable parity attentions on path 1 */
bnx2x_pretend_func(bp, 1);
bnx2x_clear_blocks_parity(bp);
bnx2x_enable_blocks_parity(bp);
/* Return to current function */
bnx2x_pretend_func(bp, BP_ABS_FUNC(bp));
}
static int bnx2x_get_preset_regs_len(struct net_device *dev, u32 preset)
@ -993,17 +975,8 @@ static int bnx2x_get_dump_data(struct net_device *dev,
* will re-enable parity attentions right after the dump.
*/
/* Disable parity on path 0 */
bnx2x_pretend_func(bp, 0);
bnx2x_disable_blocks_parity(bp);
/* Disable parity on path 1 */
bnx2x_pretend_func(bp, 1);
bnx2x_disable_blocks_parity(bp);
/* Return to current function */
bnx2x_pretend_func(bp, BP_ABS_FUNC(bp));
dump_hdr.header_size = (sizeof(struct dump_header) / 4) - 1;
dump_hdr.preset = bp->dump_preset_idx;
dump_hdr.version = BNX2X_DUMP_VERSION;
@ -1032,19 +1005,10 @@ static int bnx2x_get_dump_data(struct net_device *dev,
/* Actually read the registers */
__bnx2x_get_preset_regs(bp, p, dump_hdr.preset);
/* Re-enable parity attentions on path 0 */
bnx2x_pretend_func(bp, 0);
/* Re-enable parity attentions */
bnx2x_clear_blocks_parity(bp);
bnx2x_enable_blocks_parity(bp);
/* Re-enable parity attentions on path 1 */
bnx2x_pretend_func(bp, 1);
bnx2x_clear_blocks_parity(bp);
bnx2x_enable_blocks_parity(bp);
/* Return to current function */
bnx2x_pretend_func(bp, BP_ABS_FUNC(bp));
return 0;
}

Просмотреть файл

@ -640,23 +640,35 @@ static const struct {
* [30] MCP Latched ump_tx_parity
* [31] MCP Latched scpad_parity
*/
#define MISC_AEU_ENABLE_MCP_PRTY_BITS \
#define MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS \
(AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY | \
AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY | \
AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY | \
AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY)
#define MISC_AEU_ENABLE_MCP_PRTY_BITS \
(MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS | \
AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY)
/* Below registers control the MCP parity attention output. When
* MISC_AEU_ENABLE_MCP_PRTY_BITS are set - attentions are
* enabled, when cleared - disabled.
*/
static const u32 mcp_attn_ctl_regs[] = {
MISC_REG_AEU_ENABLE4_FUNC_0_OUT_0,
MISC_REG_AEU_ENABLE4_NIG_0,
MISC_REG_AEU_ENABLE4_PXP_0,
MISC_REG_AEU_ENABLE4_FUNC_1_OUT_0,
MISC_REG_AEU_ENABLE4_NIG_1,
MISC_REG_AEU_ENABLE4_PXP_1
static const struct {
u32 addr;
u32 bits;
} mcp_attn_ctl_regs[] = {
{ MISC_REG_AEU_ENABLE4_FUNC_0_OUT_0,
MISC_AEU_ENABLE_MCP_PRTY_BITS },
{ MISC_REG_AEU_ENABLE4_NIG_0,
MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS },
{ MISC_REG_AEU_ENABLE4_PXP_0,
MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS },
{ MISC_REG_AEU_ENABLE4_FUNC_1_OUT_0,
MISC_AEU_ENABLE_MCP_PRTY_BITS },
{ MISC_REG_AEU_ENABLE4_NIG_1,
MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS },
{ MISC_REG_AEU_ENABLE4_PXP_1,
MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS }
};
static inline void bnx2x_set_mcp_parity(struct bnx2x *bp, u8 enable)
@ -665,14 +677,14 @@ static inline void bnx2x_set_mcp_parity(struct bnx2x *bp, u8 enable)
u32 reg_val;
for (i = 0; i < ARRAY_SIZE(mcp_attn_ctl_regs); i++) {
reg_val = REG_RD(bp, mcp_attn_ctl_regs[i]);
reg_val = REG_RD(bp, mcp_attn_ctl_regs[i].addr);
if (enable)
reg_val |= MISC_AEU_ENABLE_MCP_PRTY_BITS;
reg_val |= mcp_attn_ctl_regs[i].bits;
else
reg_val &= ~MISC_AEU_ENABLE_MCP_PRTY_BITS;
reg_val &= ~mcp_attn_ctl_regs[i].bits;
REG_WR(bp, mcp_attn_ctl_regs[i], reg_val);
REG_WR(bp, mcp_attn_ctl_regs[i].addr, reg_val);
}
}

Просмотреть файл

@ -503,9 +503,9 @@ void bnx2x_prep_dmae_with_comp(struct bnx2x *bp,
}
/* issue a dmae command over the init-channel and wait for completion */
int bnx2x_issue_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae)
int bnx2x_issue_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae,
u32 *comp)
{
u32 *wb_comp = bnx2x_sp(bp, wb_comp);
int cnt = CHIP_REV_IS_SLOW(bp) ? (400000) : 4000;
int rc = 0;
@ -518,14 +518,14 @@ int bnx2x_issue_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae)
spin_lock_bh(&bp->dmae_lock);
/* reset completion */
*wb_comp = 0;
*comp = 0;
/* post the command on the channel used for initializations */
bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp));
/* wait for completion */
udelay(5);
while ((*wb_comp & ~DMAE_PCI_ERR_FLAG) != DMAE_COMP_VAL) {
while ((*comp & ~DMAE_PCI_ERR_FLAG) != DMAE_COMP_VAL) {
if (!cnt ||
(bp->recovery_state != BNX2X_RECOVERY_DONE &&
@ -537,7 +537,7 @@ int bnx2x_issue_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae)
cnt--;
udelay(50);
}
if (*wb_comp & DMAE_PCI_ERR_FLAG) {
if (*comp & DMAE_PCI_ERR_FLAG) {
BNX2X_ERR("DMAE PCI error!\n");
rc = DMAE_PCI_ERROR;
}
@ -574,7 +574,7 @@ void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
dmae.len = len32;
/* issue the command and wait for completion */
rc = bnx2x_issue_dmae_with_comp(bp, &dmae);
rc = bnx2x_issue_dmae_with_comp(bp, &dmae, bnx2x_sp(bp, wb_comp));
if (rc) {
BNX2X_ERR("DMAE returned failure %d\n", rc);
bnx2x_panic();
@ -611,7 +611,7 @@ void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
dmae.len = len32;
/* issue the command and wait for completion */
rc = bnx2x_issue_dmae_with_comp(bp, &dmae);
rc = bnx2x_issue_dmae_with_comp(bp, &dmae, bnx2x_sp(bp, wb_comp));
if (rc) {
BNX2X_ERR("DMAE returned failure %d\n", rc);
bnx2x_panic();
@ -751,6 +751,10 @@ static int bnx2x_mc_assert(struct bnx2x *bp)
return rc;
}
#define MCPR_TRACE_BUFFER_SIZE (0x800)
#define SCRATCH_BUFFER_SIZE(bp) \
(CHIP_IS_E1(bp) ? 0x10000 : (CHIP_IS_E1H(bp) ? 0x20000 : 0x28000))
void bnx2x_fw_dump_lvl(struct bnx2x *bp, const char *lvl)
{
u32 addr, val;
@ -775,7 +779,17 @@ void bnx2x_fw_dump_lvl(struct bnx2x *bp, const char *lvl)
trace_shmem_base = bp->common.shmem_base;
else
trace_shmem_base = SHMEM2_RD(bp, other_shmem_base_addr);
addr = trace_shmem_base - 0x800;
/* sanity */
if (trace_shmem_base < MCPR_SCRATCH_BASE(bp) + MCPR_TRACE_BUFFER_SIZE ||
trace_shmem_base >= MCPR_SCRATCH_BASE(bp) +
SCRATCH_BUFFER_SIZE(bp)) {
BNX2X_ERR("Unable to dump trace buffer (mark %x)\n",
trace_shmem_base);
return;
}
addr = trace_shmem_base - MCPR_TRACE_BUFFER_SIZE;
/* validate TRCB signature */
mark = REG_RD(bp, addr);
@ -787,14 +801,17 @@ void bnx2x_fw_dump_lvl(struct bnx2x *bp, const char *lvl)
/* read cyclic buffer pointer */
addr += 4;
mark = REG_RD(bp, addr);
mark = (CHIP_IS_E1x(bp) ? MCP_REG_MCPR_SCRATCH : MCP_A_REG_MCPR_SCRATCH)
+ ((mark + 0x3) & ~0x3) - 0x08000000;
mark = MCPR_SCRATCH_BASE(bp) + ((mark + 0x3) & ~0x3) - 0x08000000;
if (mark >= trace_shmem_base || mark < addr + 4) {
BNX2X_ERR("Mark doesn't fall inside Trace Buffer\n");
return;
}
printk("%s" "begin fw dump (mark 0x%x)\n", lvl, mark);
printk("%s", lvl);
/* dump buffer after the mark */
for (offset = mark; offset <= trace_shmem_base; offset += 0x8*4) {
for (offset = mark; offset < trace_shmem_base; offset += 0x8*4) {
for (word = 0; word < 8; word++)
data[word] = htonl(REG_RD(bp, offset + 4*word));
data[8] = 0x0;
@ -4280,65 +4297,60 @@ static void _print_next_block(int idx, const char *blk)
pr_cont("%s%s", idx ? ", " : "", blk);
}
static int bnx2x_check_blocks_with_parity0(struct bnx2x *bp, u32 sig,
int par_num, bool print)
static bool bnx2x_check_blocks_with_parity0(struct bnx2x *bp, u32 sig,
int *par_num, bool print)
{
int i = 0;
u32 cur_bit = 0;
u32 cur_bit;
bool res;
int i;
res = false;
for (i = 0; sig; i++) {
cur_bit = ((u32)0x1 << i);
cur_bit = (0x1UL << i);
if (sig & cur_bit) {
switch (cur_bit) {
case AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR:
if (print) {
_print_next_block(par_num++, "BRB");
res |= true; /* Each bit is real error! */
if (print) {
switch (cur_bit) {
case AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR:
_print_next_block((*par_num)++, "BRB");
_print_parity(bp,
BRB1_REG_BRB1_PRTY_STS);
}
break;
case AEU_INPUTS_ATTN_BITS_PARSER_PARITY_ERROR:
if (print) {
_print_next_block(par_num++, "PARSER");
break;
case AEU_INPUTS_ATTN_BITS_PARSER_PARITY_ERROR:
_print_next_block((*par_num)++,
"PARSER");
_print_parity(bp, PRS_REG_PRS_PRTY_STS);
}
break;
case AEU_INPUTS_ATTN_BITS_TSDM_PARITY_ERROR:
if (print) {
_print_next_block(par_num++, "TSDM");
break;
case AEU_INPUTS_ATTN_BITS_TSDM_PARITY_ERROR:
_print_next_block((*par_num)++, "TSDM");
_print_parity(bp,
TSDM_REG_TSDM_PRTY_STS);
}
break;
case AEU_INPUTS_ATTN_BITS_SEARCHER_PARITY_ERROR:
if (print) {
_print_next_block(par_num++,
break;
case AEU_INPUTS_ATTN_BITS_SEARCHER_PARITY_ERROR:
_print_next_block((*par_num)++,
"SEARCHER");
_print_parity(bp, SRC_REG_SRC_PRTY_STS);
}
break;
case AEU_INPUTS_ATTN_BITS_TCM_PARITY_ERROR:
if (print) {
_print_next_block(par_num++, "TCM");
_print_parity(bp,
TCM_REG_TCM_PRTY_STS);
}
break;
case AEU_INPUTS_ATTN_BITS_TSEMI_PARITY_ERROR:
if (print) {
_print_next_block(par_num++, "TSEMI");
break;
case AEU_INPUTS_ATTN_BITS_TCM_PARITY_ERROR:
_print_next_block((*par_num)++, "TCM");
_print_parity(bp, TCM_REG_TCM_PRTY_STS);
break;
case AEU_INPUTS_ATTN_BITS_TSEMI_PARITY_ERROR:
_print_next_block((*par_num)++,
"TSEMI");
_print_parity(bp,
TSEM_REG_TSEM_PRTY_STS_0);
_print_parity(bp,
TSEM_REG_TSEM_PRTY_STS_1);
}
break;
case AEU_INPUTS_ATTN_BITS_PBCLIENT_PARITY_ERROR:
if (print) {
_print_next_block(par_num++, "XPB");
break;
case AEU_INPUTS_ATTN_BITS_PBCLIENT_PARITY_ERROR:
_print_next_block((*par_num)++, "XPB");
_print_parity(bp, GRCBASE_XPB +
PB_REG_PB_PRTY_STS);
break;
}
break;
}
/* Clear the bit */
@ -4346,53 +4358,59 @@ static int bnx2x_check_blocks_with_parity0(struct bnx2x *bp, u32 sig,
}
}
return par_num;
return res;
}
static int bnx2x_check_blocks_with_parity1(struct bnx2x *bp, u32 sig,
int par_num, bool *global,
static bool bnx2x_check_blocks_with_parity1(struct bnx2x *bp, u32 sig,
int *par_num, bool *global,
bool print)
{
int i = 0;
u32 cur_bit = 0;
u32 cur_bit;
bool res;
int i;
res = false;
for (i = 0; sig; i++) {
cur_bit = ((u32)0x1 << i);
cur_bit = (0x1UL << i);
if (sig & cur_bit) {
res |= true; /* Each bit is real error! */
switch (cur_bit) {
case AEU_INPUTS_ATTN_BITS_PBF_PARITY_ERROR:
if (print) {
_print_next_block(par_num++, "PBF");
_print_next_block((*par_num)++, "PBF");
_print_parity(bp, PBF_REG_PBF_PRTY_STS);
}
break;
case AEU_INPUTS_ATTN_BITS_QM_PARITY_ERROR:
if (print) {
_print_next_block(par_num++, "QM");
_print_next_block((*par_num)++, "QM");
_print_parity(bp, QM_REG_QM_PRTY_STS);
}
break;
case AEU_INPUTS_ATTN_BITS_TIMERS_PARITY_ERROR:
if (print) {
_print_next_block(par_num++, "TM");
_print_next_block((*par_num)++, "TM");
_print_parity(bp, TM_REG_TM_PRTY_STS);
}
break;
case AEU_INPUTS_ATTN_BITS_XSDM_PARITY_ERROR:
if (print) {
_print_next_block(par_num++, "XSDM");
_print_next_block((*par_num)++, "XSDM");
_print_parity(bp,
XSDM_REG_XSDM_PRTY_STS);
}
break;
case AEU_INPUTS_ATTN_BITS_XCM_PARITY_ERROR:
if (print) {
_print_next_block(par_num++, "XCM");
_print_next_block((*par_num)++, "XCM");
_print_parity(bp, XCM_REG_XCM_PRTY_STS);
}
break;
case AEU_INPUTS_ATTN_BITS_XSEMI_PARITY_ERROR:
if (print) {
_print_next_block(par_num++, "XSEMI");
_print_next_block((*par_num)++,
"XSEMI");
_print_parity(bp,
XSEM_REG_XSEM_PRTY_STS_0);
_print_parity(bp,
@ -4401,7 +4419,7 @@ static int bnx2x_check_blocks_with_parity1(struct bnx2x *bp, u32 sig,
break;
case AEU_INPUTS_ATTN_BITS_DOORBELLQ_PARITY_ERROR:
if (print) {
_print_next_block(par_num++,
_print_next_block((*par_num)++,
"DOORBELLQ");
_print_parity(bp,
DORQ_REG_DORQ_PRTY_STS);
@ -4409,7 +4427,7 @@ static int bnx2x_check_blocks_with_parity1(struct bnx2x *bp, u32 sig,
break;
case AEU_INPUTS_ATTN_BITS_NIG_PARITY_ERROR:
if (print) {
_print_next_block(par_num++, "NIG");
_print_next_block((*par_num)++, "NIG");
if (CHIP_IS_E1x(bp)) {
_print_parity(bp,
NIG_REG_NIG_PRTY_STS);
@ -4423,32 +4441,34 @@ static int bnx2x_check_blocks_with_parity1(struct bnx2x *bp, u32 sig,
break;
case AEU_INPUTS_ATTN_BITS_VAUX_PCI_CORE_PARITY_ERROR:
if (print)
_print_next_block(par_num++,
_print_next_block((*par_num)++,
"VAUX PCI CORE");
*global = true;
break;
case AEU_INPUTS_ATTN_BITS_DEBUG_PARITY_ERROR:
if (print) {
_print_next_block(par_num++, "DEBUG");
_print_next_block((*par_num)++,
"DEBUG");
_print_parity(bp, DBG_REG_DBG_PRTY_STS);
}
break;
case AEU_INPUTS_ATTN_BITS_USDM_PARITY_ERROR:
if (print) {
_print_next_block(par_num++, "USDM");
_print_next_block((*par_num)++, "USDM");
_print_parity(bp,
USDM_REG_USDM_PRTY_STS);
}
break;
case AEU_INPUTS_ATTN_BITS_UCM_PARITY_ERROR:
if (print) {
_print_next_block(par_num++, "UCM");
_print_next_block((*par_num)++, "UCM");
_print_parity(bp, UCM_REG_UCM_PRTY_STS);
}
break;
case AEU_INPUTS_ATTN_BITS_USEMI_PARITY_ERROR:
if (print) {
_print_next_block(par_num++, "USEMI");
_print_next_block((*par_num)++,
"USEMI");
_print_parity(bp,
USEM_REG_USEM_PRTY_STS_0);
_print_parity(bp,
@ -4457,21 +4477,21 @@ static int bnx2x_check_blocks_with_parity1(struct bnx2x *bp, u32 sig,
break;
case AEU_INPUTS_ATTN_BITS_UPB_PARITY_ERROR:
if (print) {
_print_next_block(par_num++, "UPB");
_print_next_block((*par_num)++, "UPB");
_print_parity(bp, GRCBASE_UPB +
PB_REG_PB_PRTY_STS);
}
break;
case AEU_INPUTS_ATTN_BITS_CSDM_PARITY_ERROR:
if (print) {
_print_next_block(par_num++, "CSDM");
_print_next_block((*par_num)++, "CSDM");
_print_parity(bp,
CSDM_REG_CSDM_PRTY_STS);
}
break;
case AEU_INPUTS_ATTN_BITS_CCM_PARITY_ERROR:
if (print) {
_print_next_block(par_num++, "CCM");
_print_next_block((*par_num)++, "CCM");
_print_parity(bp, CCM_REG_CCM_PRTY_STS);
}
break;
@ -4482,80 +4502,73 @@ static int bnx2x_check_blocks_with_parity1(struct bnx2x *bp, u32 sig,
}
}
return par_num;
return res;
}
static int bnx2x_check_blocks_with_parity2(struct bnx2x *bp, u32 sig,
int par_num, bool print)
static bool bnx2x_check_blocks_with_parity2(struct bnx2x *bp, u32 sig,
int *par_num, bool print)
{
int i = 0;
u32 cur_bit = 0;
u32 cur_bit;
bool res;
int i;
res = false;
for (i = 0; sig; i++) {
cur_bit = ((u32)0x1 << i);
cur_bit = (0x1UL << i);
if (sig & cur_bit) {
switch (cur_bit) {
case AEU_INPUTS_ATTN_BITS_CSEMI_PARITY_ERROR:
if (print) {
_print_next_block(par_num++, "CSEMI");
res |= true; /* Each bit is real error! */
if (print) {
switch (cur_bit) {
case AEU_INPUTS_ATTN_BITS_CSEMI_PARITY_ERROR:
_print_next_block((*par_num)++,
"CSEMI");
_print_parity(bp,
CSEM_REG_CSEM_PRTY_STS_0);
_print_parity(bp,
CSEM_REG_CSEM_PRTY_STS_1);
}
break;
case AEU_INPUTS_ATTN_BITS_PXP_PARITY_ERROR:
if (print) {
_print_next_block(par_num++, "PXP");
break;
case AEU_INPUTS_ATTN_BITS_PXP_PARITY_ERROR:
_print_next_block((*par_num)++, "PXP");
_print_parity(bp, PXP_REG_PXP_PRTY_STS);
_print_parity(bp,
PXP2_REG_PXP2_PRTY_STS_0);
_print_parity(bp,
PXP2_REG_PXP2_PRTY_STS_1);
}
break;
case AEU_IN_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR:
if (print)
_print_next_block(par_num++,
"PXPPCICLOCKCLIENT");
break;
case AEU_INPUTS_ATTN_BITS_CFC_PARITY_ERROR:
if (print) {
_print_next_block(par_num++, "CFC");
break;
case AEU_IN_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR:
_print_next_block((*par_num)++,
"PXPPCICLOCKCLIENT");
break;
case AEU_INPUTS_ATTN_BITS_CFC_PARITY_ERROR:
_print_next_block((*par_num)++, "CFC");
_print_parity(bp,
CFC_REG_CFC_PRTY_STS);
}
break;
case AEU_INPUTS_ATTN_BITS_CDU_PARITY_ERROR:
if (print) {
_print_next_block(par_num++, "CDU");
break;
case AEU_INPUTS_ATTN_BITS_CDU_PARITY_ERROR:
_print_next_block((*par_num)++, "CDU");
_print_parity(bp, CDU_REG_CDU_PRTY_STS);
}
break;
case AEU_INPUTS_ATTN_BITS_DMAE_PARITY_ERROR:
if (print) {
_print_next_block(par_num++, "DMAE");
break;
case AEU_INPUTS_ATTN_BITS_DMAE_PARITY_ERROR:
_print_next_block((*par_num)++, "DMAE");
_print_parity(bp,
DMAE_REG_DMAE_PRTY_STS);
}
break;
case AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR:
if (print) {
_print_next_block(par_num++, "IGU");
break;
case AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR:
_print_next_block((*par_num)++, "IGU");
if (CHIP_IS_E1x(bp))
_print_parity(bp,
HC_REG_HC_PRTY_STS);
else
_print_parity(bp,
IGU_REG_IGU_PRTY_STS);
}
break;
case AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR:
if (print) {
_print_next_block(par_num++, "MISC");
break;
case AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR:
_print_next_block((*par_num)++, "MISC");
_print_parity(bp,
MISC_REG_MISC_PRTY_STS);
break;
}
break;
}
/* Clear the bit */
@ -4563,40 +4576,49 @@ static int bnx2x_check_blocks_with_parity2(struct bnx2x *bp, u32 sig,
}
}
return par_num;
return res;
}
static int bnx2x_check_blocks_with_parity3(u32 sig, int par_num,
bool *global, bool print)
static bool bnx2x_check_blocks_with_parity3(struct bnx2x *bp, u32 sig,
int *par_num, bool *global,
bool print)
{
int i = 0;
u32 cur_bit = 0;
bool res = false;
u32 cur_bit;
int i;
for (i = 0; sig; i++) {
cur_bit = ((u32)0x1 << i);
cur_bit = (0x1UL << i);
if (sig & cur_bit) {
switch (cur_bit) {
case AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY:
if (print)
_print_next_block(par_num++, "MCP ROM");
_print_next_block((*par_num)++,
"MCP ROM");
*global = true;
res |= true;
break;
case AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY:
if (print)
_print_next_block(par_num++,
_print_next_block((*par_num)++,
"MCP UMP RX");
*global = true;
res |= true;
break;
case AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY:
if (print)
_print_next_block(par_num++,
_print_next_block((*par_num)++,
"MCP UMP TX");
*global = true;
res |= true;
break;
case AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY:
if (print)
_print_next_block(par_num++,
_print_next_block((*par_num)++,
"MCP SCPAD");
*global = true;
/* clear latched SCPAD PATIRY from MCP */
REG_WR(bp, MISC_REG_AEU_CLR_LATCH_SIGNAL,
1UL << 10);
break;
}
@ -4605,45 +4627,50 @@ static int bnx2x_check_blocks_with_parity3(u32 sig, int par_num,
}
}
return par_num;
return res;
}
static int bnx2x_check_blocks_with_parity4(struct bnx2x *bp, u32 sig,
int par_num, bool print)
static bool bnx2x_check_blocks_with_parity4(struct bnx2x *bp, u32 sig,
int *par_num, bool print)
{
int i = 0;
u32 cur_bit = 0;
u32 cur_bit;
bool res;
int i;
res = false;
for (i = 0; sig; i++) {
cur_bit = ((u32)0x1 << i);
cur_bit = (0x1UL << i);
if (sig & cur_bit) {
switch (cur_bit) {
case AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR:
if (print) {
_print_next_block(par_num++, "PGLUE_B");
res |= true; /* Each bit is real error! */
if (print) {
switch (cur_bit) {
case AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR:
_print_next_block((*par_num)++,
"PGLUE_B");
_print_parity(bp,
PGLUE_B_REG_PGLUE_B_PRTY_STS);
}
break;
case AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR:
if (print) {
_print_next_block(par_num++, "ATC");
PGLUE_B_REG_PGLUE_B_PRTY_STS);
break;
case AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR:
_print_next_block((*par_num)++, "ATC");
_print_parity(bp,
ATC_REG_ATC_PRTY_STS);
break;
}
break;
}
/* Clear the bit */
sig &= ~cur_bit;
}
}
return par_num;
return res;
}
static bool bnx2x_parity_attn(struct bnx2x *bp, bool *global, bool print,
u32 *sig)
{
bool res = false;
if ((sig[0] & HW_PRTY_ASSERT_SET_0) ||
(sig[1] & HW_PRTY_ASSERT_SET_1) ||
(sig[2] & HW_PRTY_ASSERT_SET_2) ||
@ -4660,23 +4687,22 @@ static bool bnx2x_parity_attn(struct bnx2x *bp, bool *global, bool print,
if (print)
netdev_err(bp->dev,
"Parity errors detected in blocks: ");
par_num = bnx2x_check_blocks_with_parity0(bp,
sig[0] & HW_PRTY_ASSERT_SET_0, par_num, print);
par_num = bnx2x_check_blocks_with_parity1(bp,
sig[1] & HW_PRTY_ASSERT_SET_1, par_num, global, print);
par_num = bnx2x_check_blocks_with_parity2(bp,
sig[2] & HW_PRTY_ASSERT_SET_2, par_num, print);
par_num = bnx2x_check_blocks_with_parity3(
sig[3] & HW_PRTY_ASSERT_SET_3, par_num, global, print);
par_num = bnx2x_check_blocks_with_parity4(bp,
sig[4] & HW_PRTY_ASSERT_SET_4, par_num, print);
res |= bnx2x_check_blocks_with_parity0(bp,
sig[0] & HW_PRTY_ASSERT_SET_0, &par_num, print);
res |= bnx2x_check_blocks_with_parity1(bp,
sig[1] & HW_PRTY_ASSERT_SET_1, &par_num, global, print);
res |= bnx2x_check_blocks_with_parity2(bp,
sig[2] & HW_PRTY_ASSERT_SET_2, &par_num, print);
res |= bnx2x_check_blocks_with_parity3(bp,
sig[3] & HW_PRTY_ASSERT_SET_3, &par_num, global, print);
res |= bnx2x_check_blocks_with_parity4(bp,
sig[4] & HW_PRTY_ASSERT_SET_4, &par_num, print);
if (print)
pr_cont("\n");
}
return true;
} else
return false;
return res;
}
/**
@ -7126,7 +7152,7 @@ static int bnx2x_init_hw_port(struct bnx2x *bp)
int port = BP_PORT(bp);
int init_phase = port ? PHASE_PORT1 : PHASE_PORT0;
u32 low, high;
u32 val;
u32 val, reg;
DP(NETIF_MSG_HW, "starting port init port %d\n", port);
@ -7271,6 +7297,17 @@ static int bnx2x_init_hw_port(struct bnx2x *bp)
val |= CHIP_IS_E1(bp) ? 0 : 0x10;
REG_WR(bp, MISC_REG_AEU_MASK_ATTN_FUNC_0 + port*4, val);
/* SCPAD_PARITY should NOT trigger close the gates */
reg = port ? MISC_REG_AEU_ENABLE4_NIG_1 : MISC_REG_AEU_ENABLE4_NIG_0;
REG_WR(bp, reg,
REG_RD(bp, reg) &
~AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY);
reg = port ? MISC_REG_AEU_ENABLE4_PXP_1 : MISC_REG_AEU_ENABLE4_PXP_0;
REG_WR(bp, reg,
REG_RD(bp, reg) &
~AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY);
bnx2x_init_block(bp, BLOCK_NIG, init_phase);
if (!CHIP_IS_E1x(bp)) {
@ -11685,9 +11722,6 @@ static int bnx2x_init_bp(struct bnx2x *bp)
static int bnx2x_open(struct net_device *dev)
{
struct bnx2x *bp = netdev_priv(dev);
bool global = false;
int other_engine = BP_PATH(bp) ? 0 : 1;
bool other_load_status, load_status;
int rc;
bp->stats_init = true;
@ -11703,6 +11737,10 @@ static int bnx2x_open(struct net_device *dev)
* Parity recovery is only relevant for PF driver.
*/
if (IS_PF(bp)) {
int other_engine = BP_PATH(bp) ? 0 : 1;
bool other_load_status, load_status;
bool global = false;
other_load_status = bnx2x_get_load_status(bp, other_engine);
load_status = bnx2x_get_load_status(bp, BP_PATH(bp));
if (!bnx2x_reset_is_done(bp, BP_PATH(bp)) ||
@ -12080,7 +12118,6 @@ static int bnx2x_set_coherency_mask(struct bnx2x *bp)
struct device *dev = &bp->pdev->dev;
if (dma_set_mask(dev, DMA_BIT_MASK(64)) == 0) {
bp->flags |= USING_DAC_FLAG;
if (dma_set_coherent_mask(dev, DMA_BIT_MASK(64)) != 0) {
dev_err(dev, "dma_set_coherent_mask failed, aborting\n");
return -EIO;
@ -12248,8 +12285,7 @@ static int bnx2x_init_dev(struct bnx2x *bp, struct pci_dev *pdev,
NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_HIGHDMA;
dev->features |= dev->hw_features | NETIF_F_HW_VLAN_CTAG_RX;
if (bp->flags & USING_DAC_FLAG)
dev->features |= NETIF_F_HIGHDMA;
dev->features |= NETIF_F_HIGHDMA;
/* Add Loopback capability to the device */
dev->hw_features |= NETIF_F_LOOPBACK;
@ -12612,24 +12648,24 @@ static int set_max_cos_est(int chip_id)
return BNX2X_MULTI_TX_COS_E1X;
case BCM57712:
case BCM57712_MF:
case BCM57712_VF:
return BNX2X_MULTI_TX_COS_E2_E3A0;
case BCM57800:
case BCM57800_MF:
case BCM57800_VF:
case BCM57810:
case BCM57810_MF:
case BCM57840_4_10:
case BCM57840_2_20:
case BCM57840_O:
case BCM57840_MFO:
case BCM57810_VF:
case BCM57840_MF:
case BCM57840_VF:
case BCM57811:
case BCM57811_MF:
case BCM57811_VF:
return BNX2X_MULTI_TX_COS_E3B0;
case BCM57712_VF:
case BCM57800_VF:
case BCM57810_VF:
case BCM57840_VF:
case BCM57811_VF:
return 1;
default:
pr_err("Unknown board_type (%d), aborting\n", chip_id);

Просмотреть файл

@ -470,10 +470,10 @@ static int bnx2x_vfop_qdtor_cmd(struct bnx2x *bp,
bnx2x_vfop_qdtor, cmd->done);
return bnx2x_vfop_transition(bp, vf, bnx2x_vfop_qdtor,
cmd->block);
} else {
BNX2X_ERR("VF[%d] failed to add a vfop\n", vf->abs_vfid);
return -ENOMEM;
}
DP(BNX2X_MSG_IOV, "VF[%d] failed to add a vfop. rc %d\n",
vf->abs_vfid, vfop->rc);
return -ENOMEM;
}
static void
@ -3390,14 +3390,16 @@ int bnx2x_set_vf_mac(struct net_device *dev, int vfidx, u8 *mac)
rc = bnx2x_del_all_macs(bp, mac_obj, BNX2X_ETH_MAC, true);
if (rc) {
BNX2X_ERR("failed to delete eth macs\n");
return -EINVAL;
rc = -EINVAL;
goto out;
}
/* remove existing uc list macs */
rc = bnx2x_del_all_macs(bp, mac_obj, BNX2X_UC_LIST_MAC, true);
if (rc) {
BNX2X_ERR("failed to delete uc_list macs\n");
return -EINVAL;
rc = -EINVAL;
goto out;
}
/* configure the new mac to device */
@ -3405,6 +3407,7 @@ int bnx2x_set_vf_mac(struct net_device *dev, int vfidx, u8 *mac)
bnx2x_set_mac_one(bp, (u8 *)&bulletin->mac, mac_obj, true,
BNX2X_ETH_MAC, &ramrod_flags);
out:
bnx2x_unlock_vf_pf_channel(bp, vf, CHANNEL_TLV_PF_SET_MAC);
}
@ -3467,7 +3470,8 @@ int bnx2x_set_vf_vlan(struct net_device *dev, int vfidx, u16 vlan, u8 qos)
&ramrod_flags);
if (rc) {
BNX2X_ERR("failed to delete vlans\n");
return -EINVAL;
rc = -EINVAL;
goto out;
}
/* send queue update ramrod to configure default vlan and silent
@ -3501,7 +3505,8 @@ int bnx2x_set_vf_vlan(struct net_device *dev, int vfidx, u16 vlan, u8 qos)
rc = bnx2x_config_vlan_mac(bp, &ramrod_param);
if (rc) {
BNX2X_ERR("failed to configure vlan\n");
return -EINVAL;
rc = -EINVAL;
goto out;
}
/* configure default vlan to vf queue and set silent
@ -3519,18 +3524,18 @@ int bnx2x_set_vf_vlan(struct net_device *dev, int vfidx, u16 vlan, u8 qos)
rc = bnx2x_queue_state_change(bp, &q_params);
if (rc) {
BNX2X_ERR("Failed to configure default VLAN\n");
return rc;
goto out;
}
/* clear the flag indicating that this VF needs its vlan
* (will only be set if the HV configured th Vlan before vf was
* and we were called because the VF came up later
* (will only be set if the HV configured the Vlan before vf was
* up and we were called because the VF came up later
*/
out:
vf->cfg_flags &= ~VF_CFG_VLAN;
bnx2x_unlock_vf_pf_channel(bp, vf, CHANNEL_TLV_PF_SET_VLAN);
}
return 0;
return rc;
}
/* crc is the first field in the bulletin board. Compute the crc over the

Просмотреть файл

@ -196,7 +196,7 @@ static void bnx2x_hw_stats_post(struct bnx2x *bp)
} else if (bp->func_stx) {
*stats_comp = 0;
bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp));
bnx2x_issue_dmae_with_comp(bp, dmae, stats_comp);
}
}

Просмотреть файл

@ -980,7 +980,7 @@ static int bnx2x_copy32_vf_dmae(struct bnx2x *bp, u8 from_vf,
dmae.len = len32;
/* issue the command and wait for completion */
return bnx2x_issue_dmae_with_comp(bp, &dmae);
return bnx2x_issue_dmae_with_comp(bp, &dmae, bnx2x_sp(bp, wb_comp));
}
static void bnx2x_vf_mbx_resp(struct bnx2x *bp, struct bnx2x_virtf *vf)