Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4440c6f7 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'bnx2x'



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: default avatarDavid S. Miller <davem@davemloft.net>
parents 49595b7b edd31476
Loading
Loading
Loading
Loading
+10 −5
Original line number Diff line number Diff line
@@ -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 */
+2 −38
Original line number Diff line number Diff line
@@ -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;
}

+25 −13
Original line number Diff line number Diff line
@@ -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);
	}
}

+212 −176
Original line number Diff line number Diff line
@@ -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,119 +4297,120 @@ 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) {
			res |= true; /* Each bit is real error! */

			if (print) {
				switch (cur_bit) {
				case AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR:
				if (print) {
					_print_next_block(par_num++, "BRB");
					_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");
					_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");
					_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++,
					_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);
				}
					_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");
					_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");
					_print_next_block((*par_num)++, "XPB");
					_print_parity(bp, GRCBASE_XPB +
							  PB_REG_PB_PRTY_STS);
				}
					break;
				}
			}

			/* Clear the bit */
			sig &= ~cur_bit;
		}
	}

	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,121 +4502,123 @@ 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) {
			res |= true; /* Each bit is real error! */
			if (print) {
				switch (cur_bit) {
				case AEU_INPUTS_ATTN_BITS_CSEMI_PARITY_ERROR:
				if (print) {
					_print_next_block(par_num++, "CSEMI");
					_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");
					_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++,
					_print_next_block((*par_num)++,
							  "PXPPCICLOCKCLIENT");
					break;
				case AEU_INPUTS_ATTN_BITS_CFC_PARITY_ERROR:
				if (print) {
					_print_next_block(par_num++, "CFC");
					_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");
					_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");
					_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");
					_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");
					_print_next_block((*par_num)++, "MISC");
					_print_parity(bp,
						      MISC_REG_MISC_PRTY_STS);
				}
					break;
				}
			}

			/* Clear the bit */
			sig &= ~cur_bit;
		}
	}

	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) {
			res |= true; /* Each bit is real error! */
			if (print) {
				switch (cur_bit) {
				case AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR:
				if (print) {
					_print_next_block(par_num++, "PGLUE_B");
					_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");
					_print_next_block((*par_num)++, "ATC");
					_print_parity(bp,
						      ATC_REG_ATC_PRTY_STS);
				}
					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,7 +12285,6 @@ 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;

	/* Add Loopback capability to the device */
@@ -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);
Loading