Commit c9ee9206 authored by Vladislav Zolotarov's avatar Vladislav Zolotarov Committed by David S. Miller

bnx2x: 57712 parity handling

- Added support for a parity error handling for a 57712 chip.
 - Changed the parity recovery scheme from per-chip to per-engine.
Signed-off-by: default avatarVladislav Zolotarov <vladz@broadcom.com>
Signed-off-by: default avatarEilon Greenstein <eilong@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@conan.davemloft.net>
parent 619c5cb6
......@@ -733,7 +733,6 @@ struct bnx2x_common {
#define CHIP_METAL(bp) (bp->common.chip_id & 0x00000ff0)
#define CHIP_BOND_ID(bp) (bp->common.chip_id & 0x0000000f)
#define CHIP_PARITY_ENABLED(bp) (CHIP_IS_E1(bp) || CHIP_IS_E1H(bp))
#define CHIP_REV_SIM(bp) (((CHIP_REV_MASK - CHIP_REV_VAL(bp)) >>\
(CHIP_REV_SHIFT + 1)) \
<< CHIP_REV_SHIFT)
......@@ -986,11 +985,13 @@ struct hw_context {
/* forward */
struct bnx2x_ilt;
typedef enum {
enum bnx2x_recovery_state {
BNX2X_RECOVERY_DONE,
BNX2X_RECOVERY_INIT,
BNX2X_RECOVERY_WAIT,
} bnx2x_recovery_state_t;
BNX2X_RECOVERY_FAILED
};
/*
* Event queue (EQ or event ring) MC hsi
......@@ -1076,7 +1077,7 @@ struct bnx2x {
const struct iro *iro_arr;
#define IRO (bp->iro_arr)
bnx2x_recovery_state_t recovery_state;
enum bnx2x_recovery_state recovery_state;
int is_leader;
struct msix_entry *msix_table;
......@@ -1800,12 +1801,14 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
(AEU_INPUTS_ATTN_BITS_TSDM_HW_INTERRUPT | \
AEU_INPUTS_ATTN_BITS_TCM_HW_INTERRUPT | \
AEU_INPUTS_ATTN_BITS_TSEMI_HW_INTERRUPT | \
AEU_INPUTS_ATTN_BITS_PBF_HW_INTERRUPT)
AEU_INPUTS_ATTN_BITS_PBCLIENT_HW_INTERRUPT)
#define HW_PRTY_ASSERT_SET_0 (AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR | \
AEU_INPUTS_ATTN_BITS_PARSER_PARITY_ERROR | \
AEU_INPUTS_ATTN_BITS_TSDM_PARITY_ERROR | \
AEU_INPUTS_ATTN_BITS_SEARCHER_PARITY_ERROR |\
AEU_INPUTS_ATTN_BITS_TSEMI_PARITY_ERROR)
AEU_INPUTS_ATTN_BITS_TSEMI_PARITY_ERROR |\
AEU_INPUTS_ATTN_BITS_TCM_PARITY_ERROR |\
AEU_INPUTS_ATTN_BITS_PBCLIENT_PARITY_ERROR)
#define HW_INTERRUT_ASSERT_SET_1 \
(AEU_INPUTS_ATTN_BITS_QM_HW_INTERRUPT | \
AEU_INPUTS_ATTN_BITS_TIMERS_HW_INTERRUPT | \
......@@ -1818,17 +1821,22 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
AEU_INPUTS_ATTN_BITS_UPB_HW_INTERRUPT | \
AEU_INPUTS_ATTN_BITS_CSDM_HW_INTERRUPT | \
AEU_INPUTS_ATTN_BITS_CCM_HW_INTERRUPT)
#define HW_PRTY_ASSERT_SET_1 (AEU_INPUTS_ATTN_BITS_PBCLIENT_PARITY_ERROR |\
#define HW_PRTY_ASSERT_SET_1 (AEU_INPUTS_ATTN_BITS_PBF_PARITY_ERROR |\
AEU_INPUTS_ATTN_BITS_QM_PARITY_ERROR | \
AEU_INPUTS_ATTN_BITS_TIMERS_PARITY_ERROR |\
AEU_INPUTS_ATTN_BITS_XSDM_PARITY_ERROR | \
AEU_INPUTS_ATTN_BITS_XCM_PARITY_ERROR |\
AEU_INPUTS_ATTN_BITS_XSEMI_PARITY_ERROR | \
AEU_INPUTS_ATTN_BITS_DOORBELLQ_PARITY_ERROR |\
AEU_INPUTS_ATTN_BITS_NIG_PARITY_ERROR |\
AEU_INPUTS_ATTN_BITS_VAUX_PCI_CORE_PARITY_ERROR |\
AEU_INPUTS_ATTN_BITS_DEBUG_PARITY_ERROR | \
AEU_INPUTS_ATTN_BITS_USDM_PARITY_ERROR | \
AEU_INPUTS_ATTN_BITS_UCM_PARITY_ERROR |\
AEU_INPUTS_ATTN_BITS_USEMI_PARITY_ERROR | \
AEU_INPUTS_ATTN_BITS_UPB_PARITY_ERROR | \
AEU_INPUTS_ATTN_BITS_CSDM_PARITY_ERROR)
AEU_INPUTS_ATTN_BITS_CSDM_PARITY_ERROR |\
AEU_INPUTS_ATTN_BITS_CCM_PARITY_ERROR)
#define HW_INTERRUT_ASSERT_SET_2 \
(AEU_INPUTS_ATTN_BITS_CSEMI_HW_INTERRUPT | \
AEU_INPUTS_ATTN_BITS_CDU_HW_INTERRUPT | \
......@@ -1840,6 +1848,7 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR |\
AEU_INPUTS_ATTN_BITS_CFC_PARITY_ERROR | \
AEU_INPUTS_ATTN_BITS_CDU_PARITY_ERROR | \
AEU_INPUTS_ATTN_BITS_DMAE_PARITY_ERROR |\
AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR | \
AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR)
......
......@@ -1918,13 +1918,23 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
{
int i;
if (bp->state == BNX2X_STATE_CLOSED) {
/* Interface has been removed - nothing to recover */
bool global = false;
if ((bp->state == BNX2X_STATE_CLOSED) ||
(bp->state == BNX2X_STATE_ERROR)) {
/* We can get here if the driver has been unloaded
* during parity error recovery and is either waiting for a
* leader to complete or for other functions to unload and
* then ifdown has been issued. In this case we want to
* unload and let other functions to complete a recovery
* process.
*/
bp->recovery_state = BNX2X_RECOVERY_DONE;
bp->is_leader = 0;
bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RESERVED_08);
smp_wmb();
bnx2x_release_leader_lock(bp);
smp_mb();
DP(NETIF_MSG_HW, "Releasing a leadership...\n");
return -EINVAL;
}
......@@ -1953,11 +1963,27 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
if (unload_mode != UNLOAD_RECOVERY)
bnx2x_chip_cleanup(bp, unload_mode);
else {
/* Disable HW interrupts, NAPI and Tx */
/* Send the UNLOAD_REQUEST to the MCP */
bnx2x_send_unload_req(bp, unload_mode);
/*
* Prevent transactions to host from the functions on the
* engine that doesn't reset global blocks in case of global
* attention once gloabl blocks are reset and gates are opened
* (the engine which leader will perform the recovery
* last).
*/
if (!CHIP_IS_E1x(bp))
bnx2x_pf_disable(bp);
/* Disable HW interrupts, NAPI */
bnx2x_netif_stop(bp, 1);
/* Release IRQs */
bnx2x_free_irq(bp);
/* Report UNLOAD_DONE to MCP */
bnx2x_send_unload_done(bp);
}
/*
......@@ -1977,17 +2003,24 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
bp->state = BNX2X_STATE_CLOSED;
/* Check if there are pending parity attentions. If there are - set
* RECOVERY_IN_PROGRESS.
*/
if (bnx2x_chk_parity_attn(bp, &global, false)) {
bnx2x_set_reset_in_progress(bp);
/* Set RESET_IS_GLOBAL if needed */
if (global)
bnx2x_set_reset_global(bp);
}
/* The last driver must disable a "close the gate" if there is no
* parity attention or "process kill" pending.
*/
if ((!bnx2x_dec_load_cnt(bp)) && (!bnx2x_chk_parity_attn(bp)) &&
bnx2x_reset_is_done(bp))
if (!bnx2x_dec_load_cnt(bp) && bnx2x_reset_is_done(bp, BP_PATH(bp)))
bnx2x_disable_close_the_gate(bp);
/* Reset MCP mail box sequence if there is on going recovery */
if (unload_mode == UNLOAD_RECOVERY)
bp->fw_seq = 0;
return 0;
}
......
......@@ -181,6 +181,9 @@ void bnx2x_drv_pulse(struct bnx2x *bp);
void bnx2x_igu_ack_sb(struct bnx2x *bp, u8 igu_sb_id, u8 segment,
u16 index, u8 op, u8 update);
/* Disable transactions from chip to host */
void bnx2x_pf_disable(struct bnx2x *bp);
/**
* bnx2x__link_status_update - handles link status change.
*
......@@ -320,6 +323,13 @@ int bnx2x_acquire_hw_lock(struct bnx2x *bp, u32 resource);
*/
int bnx2x_release_hw_lock(struct bnx2x *bp, u32 resource);
/**
* bnx2x_release_leader_lock - release recovery leader lock
*
* @bp: driver handle
*/
int bnx2x_release_leader_lock(struct bnx2x *bp);
/**
* bnx2x_set_eth_mac - configure eth MAC address in the HW
*
......@@ -370,8 +380,10 @@ void bnx2x_set_q_rx_mode(struct bnx2x *bp, u8 cl_id,
/* Parity errors related */
void bnx2x_inc_load_cnt(struct bnx2x *bp);
u32 bnx2x_dec_load_cnt(struct bnx2x *bp);
bool bnx2x_chk_parity_attn(struct bnx2x *bp);
bool bnx2x_reset_is_done(struct bnx2x *bp);
bool bnx2x_chk_parity_attn(struct bnx2x *bp, bool *global, bool print);
bool bnx2x_reset_is_done(struct bnx2x *bp, int engine);
void bnx2x_set_reset_in_progress(struct bnx2x *bp);
void bnx2x_set_reset_global(struct bnx2x *bp);
void bnx2x_disable_close_the_gate(struct bnx2x *bp);
/**
......
......@@ -634,8 +634,7 @@ static void bnx2x_get_regs(struct net_device *dev,
}
/* Re-enable parity attentions */
bnx2x_clear_blocks_parity(bp);
if (CHIP_PARITY_ENABLED(bp))
bnx2x_enable_blocks_parity(bp);
bnx2x_enable_blocks_parity(bp);
}
static void bnx2x_get_drvinfo(struct net_device *dev,
......
......@@ -377,12 +377,15 @@ static const struct {
BLOCK_PRTY_INFO_0(PXP2, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff),
BLOCK_PRTY_INFO_1(PXP2, 0x7ff, 0x7f, 0x7f, 0x7ff),
BLOCK_PRTY_INFO(HC, 0x7, 0x7, 0x7, 0),
BLOCK_PRTY_INFO(NIG, 0xffffffff, 0x3fffffff, 0xffffffff, 0),
BLOCK_PRTY_INFO_0(NIG, 0xffffffff, 0, 0, 0xffffffff),
BLOCK_PRTY_INFO_1(NIG, 0xffff, 0, 0, 0xffff),
BLOCK_PRTY_INFO(IGU, 0x7ff, 0, 0, 0x7ff),
BLOCK_PRTY_INFO(MISC, 0x1, 0x1, 0x1, 0x1),
BLOCK_PRTY_INFO(QM, 0, 0x1ff, 0xfff, 0xfff),
BLOCK_PRTY_INFO(DORQ, 0, 0x3, 0x3, 0x3),
{GRCBASE_UPB + PB_REG_PB_PRTY_MASK,
GRCBASE_UPB + PB_REG_PB_PRTY_STS_CLR, 0,
GRCBASE_UPB + PB_REG_PB_PRTY_STS_CLR, 0xf,
{0xf, 0xf, 0xf}, "UPB"},
{GRCBASE_XPB + PB_REG_PB_PRTY_MASK,
GRCBASE_XPB + PB_REG_PB_PRTY_STS_CLR, 0,
......@@ -394,10 +397,16 @@ static const struct {
BLOCK_PRTY_INFO(DMAE, 0, 0xf, 0xf, 0xf),
BLOCK_PRTY_INFO(BRB1, 0, 0xf, 0xf, 0xf),
BLOCK_PRTY_INFO(PRS, (1<<6), 0xff, 0xff, 0xff),
BLOCK_PRTY_INFO(PBF, 0, 0, 0x3ffff, 0xfffffff),
BLOCK_PRTY_INFO(TM, 0, 0, 0x7f, 0x7f),
BLOCK_PRTY_INFO(TSDM, 0x18, 0x7ff, 0x7ff, 0x7ff),
BLOCK_PRTY_INFO(CSDM, 0x8, 0x7ff, 0x7ff, 0x7ff),
BLOCK_PRTY_INFO(USDM, 0x38, 0x7ff, 0x7ff, 0x7ff),
BLOCK_PRTY_INFO(XSDM, 0x8, 0x7ff, 0x7ff, 0x7ff),
BLOCK_PRTY_INFO(TCM, 0, 0, 0x7ffffff, 0x7ffffff),
BLOCK_PRTY_INFO(CCM, 0, 0, 0x7ffffff, 0x7ffffff),
BLOCK_PRTY_INFO(UCM, 0, 0, 0x7ffffff, 0x7ffffff),
BLOCK_PRTY_INFO(XCM, 0, 0, 0x3fffffff, 0x3fffffff),
BLOCK_PRTY_INFO_0(TSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff),
BLOCK_PRTY_INFO_1(TSEM, 0, 0x3, 0x1f, 0x3f),
BLOCK_PRTY_INFO_0(USEM, 0, 0xffffffff, 0xffffffff, 0xffffffff),
......
......@@ -1606,6 +1606,34 @@ static bool bnx2x_trylock_hw_lock(struct bnx2x *bp, u32 resource)
return false;
}
/**
* bnx2x_get_leader_lock_resource - get the recovery leader resource id
*
* @bp: driver handle
*
* Returns the recovery leader resource id according to the engine this function
* belongs to. Currently only only 2 engines is supported.
*/
static inline int bnx2x_get_leader_lock_resource(struct bnx2x *bp)
{
if (BP_PATH(bp))
return HW_LOCK_RESOURCE_RECOVERY_LEADER_1;
else
return HW_LOCK_RESOURCE_RECOVERY_LEADER_0;
}
/**
* bnx2x_trylock_leader_lock- try to aquire a leader lock.
*
* @bp: driver handle
*
* Tries to aquire a leader lock for cuurent engine.
*/
static inline bool bnx2x_trylock_leader_lock(struct bnx2x *bp)
{
return bnx2x_trylock_hw_lock(bp, bnx2x_get_leader_lock_resource(bp));
}
#ifdef BCM_CNIC
static void bnx2x_cnic_cfc_comp(struct bnx2x *bp, int cid, u8 err);
#endif
......@@ -1802,6 +1830,11 @@ int bnx2x_acquire_hw_lock(struct bnx2x *bp, u32 resource)
return -EAGAIN;
}
int bnx2x_release_leader_lock(struct bnx2x *bp)
{
return bnx2x_release_hw_lock(bp, bnx2x_get_leader_lock_resource(bp));
}
int bnx2x_release_hw_lock(struct bnx2x *bp, u32 resource)
{
u32 lock_status;
......@@ -3323,72 +3356,185 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn)
}
}
#define BNX2X_MISC_GEN_REG MISC_REG_GENERIC_POR_1
#define LOAD_COUNTER_BITS 16 /* Number of bits for load counter */
#define LOAD_COUNTER_MASK (((u32)0x1 << LOAD_COUNTER_BITS) - 1)
#define RESET_DONE_FLAG_MASK (~LOAD_COUNTER_MASK)
#define RESET_DONE_FLAG_SHIFT LOAD_COUNTER_BITS
/*
* Bits map:
* 0-7 - Engine0 load counter.
* 8-15 - Engine1 load counter.
* 16 - Engine0 RESET_IN_PROGRESS bit.
* 17 - Engine1 RESET_IN_PROGRESS bit.
* 18 - Engine0 ONE_IS_LOADED. Set when there is at least one active function
* on the engine
* 19 - Engine1 ONE_IS_LOADED.
* 20 - Chip reset flow bit. When set none-leader must wait for both engines
* leader to complete (check for both RESET_IN_PROGRESS bits and not for
* just the one belonging to its engine).
*
*/
#define BNX2X_RECOVERY_GLOB_REG MISC_REG_GENERIC_POR_1
#define BNX2X_PATH0_LOAD_CNT_MASK 0x000000ff
#define BNX2X_PATH0_LOAD_CNT_SHIFT 0
#define BNX2X_PATH1_LOAD_CNT_MASK 0x0000ff00
#define BNX2X_PATH1_LOAD_CNT_SHIFT 8
#define BNX2X_PATH0_RST_IN_PROG_BIT 0x00010000
#define BNX2X_PATH1_RST_IN_PROG_BIT 0x00020000
#define BNX2X_GLOBAL_RESET_BIT 0x00040000
/*
* Set the GLOBAL_RESET bit.
*
* Should be run under rtnl lock
*/
void bnx2x_set_reset_global(struct bnx2x *bp)
{
u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val | BNX2X_GLOBAL_RESET_BIT);
barrier();
mmiowb();
}
/*
* Clear the GLOBAL_RESET bit.
*
* Should be run under rtnl lock
*/
static inline void bnx2x_clear_reset_global(struct bnx2x *bp)
{
u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val & (~BNX2X_GLOBAL_RESET_BIT));
barrier();
mmiowb();
}
/*
* Checks the GLOBAL_RESET bit.
*
* should be run under rtnl lock
*/
static inline bool bnx2x_reset_is_global(struct bnx2x *bp)
{
u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
DP(NETIF_MSG_HW, "GEN_REG_VAL=0x%08x\n", val);
return (val & BNX2X_GLOBAL_RESET_BIT) ? true : false;
}
/*
* Clear RESET_IN_PROGRESS bit for the current engine.
*
* Should be run under rtnl lock
*/
static inline void bnx2x_set_reset_done(struct bnx2x *bp)
{
u32 val = REG_RD(bp, BNX2X_MISC_GEN_REG);
val &= ~(1 << RESET_DONE_FLAG_SHIFT);
REG_WR(bp, BNX2X_MISC_GEN_REG, val);
u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
u32 bit = BP_PATH(bp) ?
BNX2X_PATH1_RST_IN_PROG_BIT : BNX2X_PATH0_RST_IN_PROG_BIT;
/* Clear the bit */
val &= ~bit;
REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val);
barrier();
mmiowb();
}
/*
* Set RESET_IN_PROGRESS for the current engine.
*
* should be run under rtnl lock
*/
static inline void bnx2x_set_reset_in_progress(struct bnx2x *bp)
void bnx2x_set_reset_in_progress(struct bnx2x *bp)
{
u32 val = REG_RD(bp, BNX2X_MISC_GEN_REG);
val |= (1 << 16);
REG_WR(bp, BNX2X_MISC_GEN_REG, val);
u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
u32 bit = BP_PATH(bp) ?
BNX2X_PATH1_RST_IN_PROG_BIT : BNX2X_PATH0_RST_IN_PROG_BIT;
/* Set the bit */
val |= bit;
REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val);
barrier();
mmiowb();
}
/*
* Checks the RESET_IN_PROGRESS bit for the given engine.
* should be run under rtnl lock
*/
bool bnx2x_reset_is_done(struct bnx2x *bp)
bool bnx2x_reset_is_done(struct bnx2x *bp, int engine)
{
u32 val = REG_RD(bp, BNX2X_MISC_GEN_REG);
DP(NETIF_MSG_HW, "GEN_REG_VAL=0x%08x\n", val);
return (val & RESET_DONE_FLAG_MASK) ? false : true;
u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
u32 bit = engine ?
BNX2X_PATH1_RST_IN_PROG_BIT : BNX2X_PATH0_RST_IN_PROG_BIT;
/* return false if bit is set */
return (val & bit) ? false : true;
}
/*
* Increment the load counter for the current engine.
*
* should be run under rtnl lock
*/
inline void bnx2x_inc_load_cnt(struct bnx2x *bp)
void bnx2x_inc_load_cnt(struct bnx2x *bp)
{
u32 val1, val = REG_RD(bp, BNX2X_MISC_GEN_REG);
u32 val1, val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
u32 mask = BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK :
BNX2X_PATH0_LOAD_CNT_MASK;
u32 shift = BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_SHIFT :
BNX2X_PATH0_LOAD_CNT_SHIFT;
DP(NETIF_MSG_HW, "Old GEN_REG_VAL=0x%08x\n", val);
val1 = ((val & LOAD_COUNTER_MASK) + 1) & LOAD_COUNTER_MASK;
REG_WR(bp, BNX2X_MISC_GEN_REG, (val & RESET_DONE_FLAG_MASK) | val1);
/* get the current counter value */
val1 = (val & mask) >> shift;
/* increment... */
val1++;
/* clear the old value */
val &= ~mask;
/* set the new one */
val |= ((val1 << shift) & mask);
REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val);
barrier();
mmiowb();
}
/*
* should be run under rtnl lock
/**
* bnx2x_dec_load_cnt - decrement the load counter
*
* @bp: driver handle
*
* Should be run under rtnl lock.
* Decrements the load counter for the current engine. Returns
* the new counter value.
*/
u32 bnx2x_dec_load_cnt(struct bnx2x *bp)
{
u32 val1, val = REG_RD(bp, BNX2X_MISC_GEN_REG);
u32 val1, val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
u32 mask = BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK :
BNX2X_PATH0_LOAD_CNT_MASK;
u32 shift = BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_SHIFT :
BNX2X_PATH0_LOAD_CNT_SHIFT;
DP(NETIF_MSG_HW, "Old GEN_REG_VAL=0x%08x\n", val);
val1 = ((val & LOAD_COUNTER_MASK) - 1) & LOAD_COUNTER_MASK;
REG_WR(bp, BNX2X_MISC_GEN_REG, (val & RESET_DONE_FLAG_MASK) | val1);
/* get the current counter value */
val1 = (val & mask) >> shift;
/* decrement... */
val1--;
/* clear the old value */
val &= ~mask;
/* set the new one */
val |= ((val1 << shift) & mask);
REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val);
barrier();
mmiowb();
......@@ -3396,17 +3542,39 @@ u32 bnx2x_dec_load_cnt(struct bnx2x *bp)
}
/*
* Read the load counter for the current engine.
*
* should be run under rtnl lock
*/
static inline u32 bnx2x_get_load_cnt(struct bnx2x *bp)
static inline u32 bnx2x_get_load_cnt(struct bnx2x *bp, int engine)
{
return REG_RD(bp, BNX2X_MISC_GEN_REG) & LOAD_COUNTER_MASK;
u32 mask = (engine ? BNX2X_PATH1_LOAD_CNT_MASK :
BNX2X_PATH0_LOAD_CNT_MASK);
u32 shift = (engine ? BNX2X_PATH1_LOAD_CNT_SHIFT :
BNX2X_PATH0_LOAD_CNT_SHIFT);
u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
DP(NETIF_MSG_HW, "GLOB_REG=0x%08x\n", val);
val = (val & mask) >> shift;
DP(NETIF_MSG_HW, "load_cnt for engine %d = %d\n", engine, val);
return val;
}
/*
* Reset the load counter for the current engine.
*
* should be run under rtnl lock
*/
static inline void bnx2x_clear_load_cnt(struct bnx2x *bp)
{
u32 val = REG_RD(bp, BNX2X_MISC_GEN_REG);
REG_WR(bp, BNX2X_MISC_GEN_REG, val & (~LOAD_COUNTER_MASK));
u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
u32 mask = (BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK :
BNX2X_PATH0_LOAD_CNT_MASK);
REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val & (~mask));
}
static inline void _print_next_block(int idx, const char *blk)
......@@ -3416,7 +3584,8 @@ static inline void _print_next_block(int idx, const char *blk)
pr_cont("%s", blk);
}
static inline int bnx2x_print_blocks_with_parity0(u32 sig, int par_num)
static inline int bnx2x_check_blocks_with_parity0(u32 sig, int par_num,
bool print)
{
int i = 0;
u32 cur_bit = 0;
......@@ -3425,19 +3594,33 @@ static inline int bnx2x_print_blocks_with_parity0(u32 sig, int par_num)
if (sig & cur_bit) {
switch (cur_bit) {
case AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR:
_print_next_block(par_num++, "BRB");
if (print)
_print_next_block(par_num++, "BRB");
break;
case AEU_INPUTS_ATTN_BITS_PARSER_PARITY_ERROR:
_print_next_block(par_num++, "PARSER");
if (print)
_print_next_block(par_num++, "PARSER");
break;
case AEU_INPUTS_ATTN_BITS_TSDM_PARITY_ERROR:
_print_next_block(par_num++, "TSDM");
if (print)
_print_next_block(par_num++, "TSDM");
break;
case AEU_INPUTS_ATTN_BITS_SEARCHER_PARITY_ERROR:
_print_next_block(par_num++, "SEARCHER");
if (print)
_print_next_block(par_num++,
"SEARCHER");
break;
case AEU_INPUTS_ATTN_BITS_TCM_PARITY_ERROR:
if (print)
_print_next_block(par_num++, "TCM");
break;
case AEU_INPUTS_ATTN_BITS_TSEMI_PARITY_ERROR:
_print_next_block(par_num++, "TSEMI");
if (print)
_print_next_block(par_num++, "TSEMI");
break;
case AEU_INPUTS_ATTN_BITS_PBCLIENT_PARITY_ERROR:
if (print)
_print_next_block(par_num++, "XPB");
break;
}
......@@ -3449,7 +3632,8 @@ static inline int bnx2x_print_blocks_with_parity0(u32 sig, int par_num)
return par_num;
}
static inline int bnx2x_print_blocks_with_parity1(u32 sig, int par_num)
static inline int bnx2x_check_blocks_with_parity1(u32 sig, int par_num,
bool *global, bool print)
{
int i = 0;
u32 cur_bit = 0;
......@@ -3457,38 +3641,64 @@ static inline int bnx2x_print_blocks_with_parity1(u32 sig, int par_num)
cur_bit = ((u32)0x1 << i);
if (sig & cur_bit) {
switch (cur_bit) {
case AEU_INPUTS_ATTN_BITS_PBCLIENT_PARITY_ERROR:
_print_next_block(par_num++, "PBCLIENT");
case AEU_INPUTS_ATTN_BITS_PBF_PARITY_ERROR:
if (print)
_print_next_block(par_num++, "PBF");
break;
case AEU_INPUTS_ATTN_BITS_QM_PARITY_ERROR:
_print_next_block(par_num++, "QM");
if (print)
_print_next_block(par_num++, "QM");
break;
case AEU_INPUTS_ATTN_BITS_TIMERS_PARITY_ERROR:
if (print)
_print_next_block(par_num++, "TM");
break;
case AEU_INPUTS_ATTN_BITS_XSDM_PARITY_ERROR:
_print_next_block(par_num++, "XSDM");
if (print)
_print_next_block(par_num++, "XSDM");
break;
case AEU_INPUTS_ATTN_BITS_XCM_PARITY_ERROR:
if (print)
_print_next_block(par_num++, "XCM");
break;
case AEU_INPUTS_ATTN_BITS_XSEMI_PARITY_ERROR:
_print_next_block(par_num++, "XSEMI");
if (print)
_print_next_block(par_num++, "XSEMI");
break;
case AEU_INPUTS_ATTN_BITS_DOORBELLQ_PARITY_ERROR:
_print_next_block(par_num++, "DOORBELLQ");
if (print)
_print_next_block(par_num++,
"DOORBELLQ");
break;
case AEU_INPUTS_ATTN_BITS_NIG_PARITY_ERROR:
if (print)
_print_next_block(par_num++, "NIG");
break;
case AEU_INPUTS_ATTN_BITS_VAUX_PCI_CORE_PARITY_ERROR:
_print_next_block(par_num++, "VAUX PCI CORE");
if (print)
_print_next_block(par_num++,
"VAUX PCI CORE");
*global = true;
break;
case AEU_INPUTS_ATTN_BITS_DEBUG_PARITY_ERROR:
_print_next_block(par_num++, "DEBUG");
if (print)
_print_next_block(par_num++, "DEBUG");
break;
case AEU_INPUTS_ATTN_BITS_USDM_PARITY_ERROR:
_print_next_block(par_num++, "USDM");
if (print)
_print_next_block(par_num++, "USDM");
break;
case AEU_INPUTS_ATTN_BITS_USEMI_PARITY_ERROR:
_print_next_block(par_num++, "USEMI");
if (print)
_print_next_block(par_num++, "USEMI");
break;
case AEU_INPUTS_ATTN_BITS_UPB_PARITY_ERROR:
_print_next_block(par_num++, "UPB");
if (print)
_print_next_block(par_num++, "UPB");
break;
case AEU_INPUTS_ATTN_BITS_CSDM_PARITY_ERROR:
_print_next_block(par_num++, "CSDM");
if (print)
_print_next_block(par_num++, "CSDM");
break;
}
......@@ -3500,7 +3710,8 @@ static inline int bnx2x_print_blocks_with_parity1(u32 sig, int par_num)
return par_num;
}
static inline int bnx2x_print_blocks_with_parity2(u32 sig, int par_num)
static inline int bnx2x_check_blocks_with_parity2(u32 sig, int par_num,
bool print)
{
int i = 0;
u32 cur_bit = 0;
......@@ -3509,26 +3720,37 @@ static inline int bnx2x_print_blocks_with_parity2(u32 sig, int par_num)
if (sig & cur_bit) {
switch (cur_bit) {
case AEU_INPUTS_ATTN_BITS_CSEMI_PARITY_ERROR:
_print_next_block(par_num++, "CSEMI");
if (print)
_print_next_block(par_num++, "CSEMI");
break;
case AEU_INPUTS_ATTN_BITS_PXP_PARITY_ERROR:
_print_next_block(par_num++, "PXP");
if (print)
_print_next_block(par_num++, "PXP");
break;
case AEU_IN_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR:
_print_next_block(par_num++,
if (print)
_print_next_block(par_num++,
"PXPPCICLOCKCLIENT");
break;
case AEU_INPUTS_ATTN_BITS_CFC_PARITY_ERROR:
_print_next_block(par_num++, "CFC");
if (print)
_print_next_block(par_num++, "CFC");
break;
case AEU_INPUTS_ATTN_BITS_CDU_PARITY_ERROR:
_print_next_block(par_num++, "CDU");
if (print)
_print_next_block(par_num++, "CDU");
break;
case AEU_INPUTS_ATTN_BITS_DMAE_PARITY_ERROR:
if (print)
_print_next_block(par_num++, "DMAE");
break;
case AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR:
_print_next_block(par_num++, "IGU");
if (print)
_print_next_block(par_num++, "IGU");
break;
case AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR:
_print_next_block(par_num++, "MISC");
if (print)
_print_next_block(par_num++, "MISC");
break;
}
......@@ -3540,7 +3762,8 @@ static inline int bnx2x_print_blocks_with_parity2(u32 sig, int par_num)
return par_num;
}
static inline int bnx2x_print_blocks_with_parity3(u32 sig, int par_num)
static inline int bnx2x_check_blocks_with_parity3(u32 sig, int par_num,
bool *global, bool print)
{
int i = 0;
u32 cur_bit = 0;
......@@ -3549,16 +3772,27 @@ static inline int bnx2x_print_blocks_with_parity3(u32 sig, int par_num)
if (sig & cur_bit) {
switch (cur_bit) {
case AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY:
_print_next_block(par_num++, "MCP ROM");
if (print)
_print_next_block(par_num++, "MCP ROM");
*global = true;
break;
case AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY:
_print_next_block(par_num++, "MCP UMP RX");
if (print)
_print_next_block(par_num++,
"MCP UMP RX");
*global = true;
break;
case AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY:
_print_next_block(par_num++, "MCP UMP TX");
if (print)
_print_next_block(par_num++,
"MCP UMP TX");
*global = true;
break;
case AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY:
_print_next_block(par_num++, "MCP SCPAD");
if (print)
_print_next_block(par_num++,
"MCP SCPAD");
*global = true;
break;
}
......@@ -3570,8 +3804,8 @@ static inline int bnx2x_print_blocks_with_parity3(u32 sig, int par_num)
return par_num;
}
static inline bool bnx2x_parity_attn(struct bnx2x *bp, u32 sig0, u32 sig1,
u32 sig2, u32 sig3)
static inline bool bnx2x_parity_attn(struct bnx2x *bp, bool *global, bool print,
u32 sig0, u32 sig1, u32 sig2, u32 sig3)
{
if ((sig0 & HW_PRTY_ASSERT_SET_0) || (sig1 & HW_PRTY_ASSERT_SET_1) ||
(sig2 & HW_PRTY_ASSERT_SET_2) || (sig3 & HW_PRTY_ASSERT_SET_3)) {
......@@ -3583,23 +3817,32 @@ static inline bool bnx2x_parity_attn(struct bnx2x *bp, u32 sig0, u32 sig1,
sig1 & HW_PRTY_ASSERT_SET_1,
sig2 & HW_PRTY_ASSERT_SET_2,
sig3 & HW_PRTY_ASSERT_SET_3);
printk(KERN_ERR"%s: Parity errors detected in blocks: ",
bp->dev->name);
par_num = bnx2x_print_blocks_with_parity0(
sig0 & HW_PRTY_ASSERT_SET_0, par_num);
par_num = bnx2x_print_blocks_with_parity1(
sig1 & HW_PRTY_ASSERT_SET_1, par_num);
par_num = bnx2x_print_blocks_with_parity2(
sig2 & HW_PRTY_ASSERT_SET_2, par_num);
par_num = bnx2x_print_blocks_with_parity3(
sig3 & HW_PRTY_ASSERT_SET_3, par_num);
printk("\n");
if (print)
netdev_err(bp->dev,
"Parity errors detected in blocks: ");
par_num = bnx2x_check_blocks_with_parity0(
sig0 & HW_PRTY_ASSERT_SET_0, par_num, print);
par_num = bnx2x_check_blocks_with_parity1(
sig1 & HW_PRTY_ASSERT_SET_1, par_num, global, print);
par_num = bnx2x_check_blocks_with_parity2(
sig2 & HW_PRTY_ASSERT_SET_2, par_num, print);
par_num = bnx2x_check_blocks_with_parity3(
sig3 & HW_PRTY_ASSERT_SET_3, par_num, global, print);
if (print)
pr_cont("\n");
return true;
} else
return false;
}
bool bnx2x_chk_parity_attn(struct bnx2x *bp)
/**
* bnx2x_chk_parity_attn - checks for parity attentions.
*
* @bp: driver handle
* @global: true if there was a global attention
* @print: show parity attention in syslog
*/
bool bnx2x_chk_parity_attn(struct bnx2x *bp, bool *global, bool print)
{
struct attn_route attn;
int port = BP_PORT(bp);
......@@ -3617,8 +3860,8 @@ bool bnx2x_chk_parity_attn(struct bnx2x *bp)
MISC_REG_AEU_AFTER_INVERT_4_FUNC_0 +
port*4);
return bnx2x_parity_attn(bp, attn.sig[0], attn.sig[1], attn.sig[2],
attn.sig[3]);
return bnx2x_parity_attn(bp, global, print, attn.sig[0], attn.sig[1],
attn.sig[2], attn.sig[3]);
}
......@@ -3697,21 +3940,25 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted)
u32 reg_addr;
u32 val;
u32 aeu_mask;
bool global = false;
/* need to take HW lock because MCP or other port might also
try to handle this event */
bnx2x_acquire_alr(bp);
if (CHIP_PARITY_ENABLED(bp) && bnx2x_chk_parity_attn(bp)) {
if (bnx2x_chk_parity_attn(bp, &global, true)) {
#ifndef BNX2X_STOP_ON_ERROR
bp->recovery_state = BNX2X_RECOVERY_INIT;
bnx2x_set_reset_in_progress(bp);
schedule_delayed_work(&bp->reset_task, 0);
/* Disable HW interrupts */
bnx2x_int_disable(bp);
bnx2x_release_alr(bp);
/* In case of parity errors don't handle attentions so that
* other function would "see" parity errors.
*/
#else
bnx2x_panic();
#endif
bnx2x_release_alr(bp);
return;
}
......@@ -5289,7 +5536,7 @@ static void bnx2x_pretend_func(struct bnx2x *bp, u8 pretend_func_num)
DP(NETIF_MSG_HW, "Pretending to func %d\n", pretend_func_num);
}
static void bnx2x_pf_disable(struct bnx2x *bp)
void bnx2x_pf_disable(struct bnx2x *bp)
{
u32 val = REG_RD(bp, IGU_REG_PF_CONFIGURATION);
val &= ~IGU_PF_CONF_FUNC_EN;
......@@ -5733,8 +5980,7 @@ static int bnx2x_init_hw_common(struct bnx2x *bp)
REG_RD(bp, PXP2_REG_PXP2_INT_STS_CLR_0);
bnx2x_enable_blocks_attention(bp);
if (CHIP_PARITY_ENABLED(bp))
bnx2x_enable_blocks_parity(bp);
bnx2x_enable_blocks_parity(bp);
if (!BP_NOMCP(bp)) {
if (CHIP_IS_E1x(bp))
......@@ -7165,24 +7411,37 @@ void bnx2x_disable_close_the_gate(struct bnx2x *bp)
/* Close gates #2, #3 and #4: */
static void bnx2x_set_234_gates(struct bnx2x *bp, bool close)
{
u32 val, addr;
u32 val;
/* Gates #2 and #4a are closed/opened for "not E1" only */
if (!CHIP_IS_E1(bp)) {
/* #4 */
val = REG_RD(bp, PXP_REG_HST_DISCARD_DOORBELLS);
REG_WR(bp, PXP_REG_HST_DISCARD_DOORBELLS,
close ? (val | 0x1) : (val & (~(u32)1)));
REG_WR(bp, PXP_REG_HST_DISCARD_DOORBELLS, !!close);
/* #2 */
val = REG_RD(bp, PXP_REG_HST_DISCARD_INTERNAL_WRITES);
REG_WR(bp, PXP_REG_HST_DISCARD_INTERNAL_WRITES,
close ? (val | 0x1) : (val & (~(u32)1)));
REG_WR(bp, PXP_REG_HST_DISCARD_INTERNAL_WRITES, !!close);
}
/* #3 */
addr = BP_PORT(bp) ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0;
val = REG_RD(bp, addr);
REG_WR(bp, addr, (!close) ? (val | 0x1) : (val & (~(u32)1)));
if (CHIP_IS_E1x(bp)) {
/* Prevent interrupts from HC on both ports */
val = REG_RD(bp, HC_REG_CONFIG_1);
REG_WR(bp, HC_REG_CONFIG_1,
(!close) ? (val | HC_CONFIG_1_REG_BLOCK_DISABLE_1) :
(val & ~(u32)HC_CONFIG_1_REG_BLOCK_DISABLE_1));
val = REG_RD(bp, HC_REG_CONFIG_0);
REG_WR(bp, HC_REG_CONFIG_0,
(!close) ? (val | HC_CONFIG_0_REG_BLOCK_DISABLE_0) :
(val & ~(u32)HC_CONFIG_0_REG_BLOCK_DISABLE_0));
} else {
/* Prevent incomming interrupts in IGU */
val = REG_RD(bp, IGU_REG_BLOCK_CONFIGURATION);
REG_WR(bp, IGU_REG_BLOCK_CONFIGURATION,
(!close) ?
(val | IGU_BLOCK_CONFIGURATION_REG_BLOCK_ENABLE) :
(val & ~(u32)IGU_BLOCK_CONFIGURATION_REG_BLOCK_ENABLE));
}
DP(NETIF_MSG_HW, "%s gates #2, #3 and #4\n",
close ? "closing" : "opening");
......@@ -7300,7 +7559,6 @@ static void bnx2x_pxp_prep(struct bnx2x *bp)
if (!CHIP_IS_E1(bp)) {
REG_WR(bp, PXP2_REG_RD_START_INIT, 0);
REG_WR(bp, PXP2_REG_RQ_RBC_DONE, 0);
REG_WR(bp, PXP2_REG_RQ_CFG_DONE, 0);
mmiowb();
}
}
......@@ -7315,9 +7573,18 @@ static void bnx2x_pxp_prep(struct bnx2x *bp)
* - GRC
* - RBCN, RBCP
*/
static void bnx2x_process_kill_chip_reset(struct bnx2x *bp)
static void bnx2x_process_kill_chip_reset(struct bnx2x *bp, bool global)
{
u32 not_reset_mask1, reset_mask1, not_reset_mask2, reset_mask2;
u32 global_bits2;
/*
* Bits that have to be set in reset_mask2 if we want to reset 'global'
* (per chip) blocks.
*/
global_bits2 =
MISC_REGISTERS_RESET_REG_2_RST_MCP_N_RESET_CMN_CPU |
MISC_REGISTERS_RESET_REG_2_RST_MCP_N_RESET_CMN_CORE;
not_reset_mask1 =
MISC_REGISTERS_RESET_REG_1_RST_HC |
......@@ -7325,7 +7592,7 @@ static void bnx2x_process_kill_chip_reset(struct bnx2x *bp)
MISC_REGISTERS_RESET_REG_1_RST_PXP;
not_reset_mask2 =
MISC_REGISTERS_RESET_REG_2_RST_MDIO |
MISC_REGISTERS_RESET_REG_2_RST_PCI_MDIO |
MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE |
MISC_REGISTERS_RESET_REG_2_RST_EMAC1_HARD_CORE |
MISC_REGISTERS_RESET_REG_2_RST_MISC_CORE |
......@@ -7341,20 +7608,76 @@ static void bnx2x_process_kill_chip_reset(struct bnx2x *bp)
else
reset_mask2 = 0x1ffff;
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR,
reset_mask1 & (~not_reset_mask1));
if (CHIP_IS_E3(bp)) {
reset_mask2 |= MISC_REGISTERS_RESET_REG_2_MSTAT0;
reset_mask2 |= MISC_REGISTERS_RESET_REG_2_MSTAT1;
}
/* Don't reset global blocks unless we need to */
if (!global)
reset_mask2 &= ~global_bits2;
/*
* In case of attention in the QM, we need to reset PXP
* (MISC_REGISTERS_RESET_REG_2_RST_PXP_RQ_RD_WR) before QM
* because otherwise QM reset would release 'close the gates' shortly
* before resetting the PXP, then the PSWRQ would send a write
* request to PGLUE. Then when PXP is reset, PGLUE would try to
* read the payload data from PSWWR, but PSWWR would not
* respond. The write queue in PGLUE would stuck, dmae commands
* would not return. Therefore it's important to reset the second
* reset register (containing the
* MISC_REGISTERS_RESET_REG_2_RST_PXP_RQ_RD_WR bit) before the
* first one (containing the MISC_REGISTERS_RESET_REG_1_RST_QM
* bit).
*/
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
reset_mask2 & (~not_reset_mask2));
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR,
reset_mask1 & (~not_reset_mask1));
barrier();
mmiowb();
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, reset_mask1);
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, reset_mask2);
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, reset_mask1);
mmiowb();
}
static int bnx2x_process_kill(struct bnx2x *bp)
/**
* bnx2x_er_poll_igu_vq - poll for pending writes bit.
* It should get cleared in no more than 1s.
*
* @bp: driver handle
*
* It should get cleared in no more than 1s. Returns 0 if
* pending writes bit gets cleared.
*/
static int bnx2x_er_poll_igu_vq(struct bnx2x *bp)
{
u32 cnt = 1000;
u32 pend_bits = 0;
do {
pend_bits = REG_RD(bp, IGU_REG_PENDING_BITS_STATUS);
if (pend_bits == 0)
break;
usleep_range(1000, 1000);
} while (cnt-- > 0);
if (cnt <= 0) {
BNX2X_ERR("Still pending IGU requests pend_bits=%x!\n",
pend_bits);
return -EBUSY;
}
return 0;
}
static int bnx2x_process_kill(struct bnx2x *bp, bool global)
{
int cnt = 1000;
u32 val = 0;
......@@ -7373,7 +7696,7 @@ static int bnx2x_process_kill(struct bnx2x *bp)
((port_is_idle_1 & 0x1) == 0x1) &&
(pgl_exp_rom2 == 0xffffffff))
break;
msleep(1);
usleep_range(1000, 1000);
} while (cnt-- > 0);
if (cnt <= 0) {
......@@ -7393,6 +7716,11 @@ static int bnx2x_process_kill(struct bnx2x *bp)
/* Close gates #2, #3 and #4 */
bnx2x_set_234_gates(bp, true);
/* Poll for IGU VQs for 57712 and newer chips */
if (!CHIP_IS_E1x(bp) && bnx2x_er_poll_igu_vq(bp))
return -EAGAIN;
/* TBD: Indicate that "process kill" is in progress to MCP */
/* Clear "unprepared" bit */
......@@ -7405,25 +7733,28 @@ static int bnx2x_process_kill(struct bnx2x *bp)
/* Wait for 1ms to empty GLUE and PCI-E core queues,
* PSWHST, GRC and PSWRD Tetris buffer.
*/
msleep(1);
usleep_range(1000, 1000);
/* Prepare to chip reset: */
/* MCP */
bnx2x_reset_mcp_prep(bp, &val);
if (global)
bnx2x_reset_mcp_prep(bp, &val);
/* PXP */
bnx2x_pxp_prep(bp);
barrier();
/* reset the chip */
bnx2x_process_kill_chip_reset(bp);
bnx2x_process_kill_chip_reset(bp, global);
barrier();
/* Recover after reset: */
/* MCP */
if (bnx2x_reset_mcp_comp(bp, val))
if (global && bnx2x_reset_mcp_comp(bp, val))
return -EAGAIN;
/* TBD: Add resetting the NO_MCP mode DB here */
/* PXP */
bnx2x_pxp_prep(bp);
......@@ -7436,43 +7767,85 @@ static int bnx2x_process_kill(struct bnx2x *bp)
return 0;
}
static int bnx2x_leader_reset(struct bnx2x *bp)
int bnx2x_leader_reset(struct bnx2x *bp)
{
int rc = 0;
bool global = bnx2x_reset_is_global(bp);
/* Try to recover after the failure */
if (bnx2x_process_kill(bp)) {
printk(KERN_ERR "%s: Something bad had happen! Aii!\n",
bp->dev->name);
if (bnx2x_process_kill(bp, global)) {
netdev_err(bp->dev, "Something bad had happen on engine %d! "
"Aii!\n", BP_PATH(bp));
rc = -EAGAIN;
goto exit_leader_reset;
}
/* Clear "reset is in progress" bit and update the driver state */
/*
* Clear RESET_IN_PROGRES and RESET_GLOBAL bits and update the driver
* state.
*/
bnx2x_set_reset_done(bp);
bp->recovery_state = BNX2X_RECOVERY_DONE;
if (global)
bnx2x_clear_reset_global(bp);
exit_leader_reset:
bp->is_leader = 0;
bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RESERVED_08);
smp_wmb();
bnx2x_release_leader_lock(bp);
smp_mb();
return rc;
}
/* Assumption: runs under rtnl lock. This together with the fact
static inline void bnx2x_recovery_failed(struct bnx2x *bp)
{
netdev_err(bp->dev, "Recovery has failed. Power cycle is needed.\n");
/* Disconnect this device */
netif_device_detach(bp->dev);
/*
* Block ifup for all function on this engine until "process kill"
* or power cycle.
*/
bnx2x_set_reset_in_progress(bp);
/* Shut down the power */
bnx2x_set_power_state(bp, PCI_D3hot);
bp->recovery_state = BNX2X_RECOVERY_FAILED;
smp_mb();
}
/*
* Assumption: runs under rtnl lock. This together with the fact
* that it's called only from bnx2x_reset_task() ensure that it
* will never be called when netif_running(bp->dev) is false.
*/
static void bnx2x_parity_recover(struct bnx2x *bp)
{
bool global = false;
DP(NETIF_MSG_HW, "Handling parity\n");
while (1) {
switch (bp->recovery_state) {
case BNX2X_RECOVERY_INIT:
DP(NETIF_MSG_HW, "State is BNX2X_RECOVERY_INIT\n");
bnx2x_chk_parity_attn(bp, &global, false);
/* Try to get a LEADER_LOCK HW lock */
if (bnx2x_trylock_hw_lock(bp,
HW_LOCK_RESOURCE_RESERVED_08))
if (bnx2x_trylock_leader_lock(bp)) {
bnx2x_set_reset_in_progress(bp);
/*
* Check if there is a global attention and if
* there was a global attention, set the global
* reset bit.
*/
if (global)
bnx2x_set_reset_global(bp);
bp->is_leader = 1;
}
/* Stop the driver */
/* If interface has been removed - break */
......@@ -7480,17 +7853,43 @@ static void bnx2x_parity_recover(struct bnx2x *bp)
return;
bp->recovery_state = BNX2X_RECOVERY_WAIT;
/* Ensure "is_leader" and "recovery_state"
* update values are seen on other CPUs
/*
* Reset MCP command sequence number and MCP mail box
* sequence as we are going to reset the MCP.
*/
if (global) {
bp->fw_seq = 0;
bp->fw_drv_pulse_wr_seq = 0;
}
/* Ensure "is_leader", MCP command sequence and
* "recovery_state" update values are seen on other
* CPUs.
*/
smp_wmb();
smp_mb();
break;
case BNX2X_RECOVERY_WAIT:
DP(NETIF_MSG_HW, "State is BNX2X_RECOVERY_WAIT\n");
if (bp->is_leader) {
u32 load_counter = bnx2x_get_load_cnt(bp);
if (load_counter) {
int other_engine = BP_PATH(bp) ? 0 : 1;
u32 other_load_counter =
bnx2x_get_load_cnt(bp, other_engine);
u32 load_counter =
bnx2x_get_load_cnt(bp, BP_PATH(bp));
global = bnx2x_reset_is_global(bp);
/*
* In case of a parity in a global block, let
* the first leader that performs a
* leader_reset() reset the global blocks in
* order to clear global attentions. Otherwise
* the the gates will remain closed for that
* engine.
*/
if (load_counter ||
(global && other_load_counter)) {
/* Wait until all other functions get
* down.
*/
......@@ -7503,37 +7902,27 @@ static void bnx2x_parity_recover(struct bnx2x *bp)
* normal. In any case it's an exit
* point for a leader.
*/
if (bnx2x_leader_reset(bp) ||
bnx2x_nic_load(bp, LOAD_NORMAL)) {
printk(KERN_ERR"%s: Recovery "
"has failed. Power cycle is "
"needed.\n", bp->dev->name);
/* Disconnect this device */
netif_device_detach(bp->dev);
/* Block ifup for all function
* of this ASIC until
* "process kill" or power
* cycle.
*/
bnx2x_set_reset_in_progress(bp);
/* Shut down the power */
bnx2x_set_power_state(bp,
PCI_D3hot);
if (bnx2x_leader_reset(bp)) {
bnx2x_recovery_failed(bp);
return;
}
return;
/* If we are here, means that the
* leader has succeeded and doesn't
* want to be a leader any more. Try
* to continue as a none-leader.
*/
break;
}
} else { /* non-leader */
if (!bnx2x_reset_is_done(bp)) {
if (!bnx2x_reset_is_done(bp, BP_PATH(bp))) {
/* Try to get a LEADER_LOCK HW lock as
* long as a former leader may have
* been unloaded by the user or
* released a leadership by another
* reason.
*/
if (bnx2x_trylock_hw_lock(bp,
HW_LOCK_RESOURCE_RESERVED_08)) {
if (bnx2x_trylock_leader_lock(bp)) {
/* I'm a leader now! Restart a
* switch case.
*/
......@@ -7545,14 +7934,25 @@ static void bnx2x_parity_recover(struct bnx2x *bp)
HZ/10);
return;
} else { /* A leader has completed
* the "process kill". It's an exit
* point for a non-leader.
*/
bnx2x_nic_load(bp, LOAD_NORMAL);
bp->recovery_state =
BNX2X_RECOVERY_DONE;
smp_wmb();
} else {
/*
* If there was a global attention, wait
* for it to be cleared.
*/
if (bnx2x_reset_is_global(bp)) {
schedule_delayed_work(
&bp->reset_task, HZ/10);
return;
}
if (bnx2x_nic_load(bp, LOAD_NORMAL))
bnx2x_recovery_failed(bp);
else {
bp->recovery_state =
BNX2X_RECOVERY_DONE;
smp_mb();
}
return;
}
}
......@@ -8871,45 +9271,62 @@ static int __devinit 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;
u32 other_load_counter, load_counter;
netif_carrier_off(dev);
bnx2x_set_power_state(bp, PCI_D0);
if (!bnx2x_reset_is_done(bp)) {
other_load_counter = bnx2x_get_load_cnt(bp, other_engine);
load_counter = bnx2x_get_load_cnt(bp, BP_PATH(bp));
/*
* If parity had happen during the unload, then attentions
* and/or RECOVERY_IN_PROGRES may still be set. In this case we
* want the first function loaded on the current engine to
* complete the recovery.
*/
if (!bnx2x_reset_is_done(bp, BP_PATH(bp)) ||
bnx2x_chk_parity_attn(bp, &global, true))
do {
/* Reset MCP mail box sequence if there is on going
* recovery
/*
* If there are attentions and they are in a global
* blocks, set the GLOBAL_RESET bit regardless whether
* it will be this function that will complete the
* recovery or not.
*/
bp->fw_seq = 0;
if (global)
bnx2x_set_reset_global(bp);
/* If it's the first function to load and reset done
* is still not cleared it may mean that. We don't
* check the attention state here because it may have
* already been cleared by a "common" reset but we
* shell proceed with "process kill" anyway.
/*
* Only the first function on the current engine should
* try to recover in open. In case of attentions in
* global blocks only the first in the chip should try
* to recover.
*/
if ((bnx2x_get_load_cnt(bp) == 0) &&
bnx2x_trylock_hw_lock(bp,
HW_LOCK_RESOURCE_RESERVED_08) &&
(!bnx2x_leader_reset(bp))) {
DP(NETIF_MSG_HW, "Recovered in open\n");
if ((!load_counter &&
(!global || !other_load_counter)) &&
bnx2x_trylock_leader_lock(bp) &&
!bnx2x_leader_reset(bp)) {
netdev_info(bp->dev, "Recovered in open\n");
break;
}
/* recovery has failed... */
bnx2x_set_power_state(bp, PCI_D3hot);
bp->recovery_state = BNX2X_RECOVERY_FAILED;
printk(KERN_ERR"%s: Recovery flow hasn't been properly"
netdev_err(bp->dev, "Recovery flow hasn't been properly"
" completed yet. Try again later. If u still see this"
" message after a few retries then power cycle is"
" required.\n", bp->dev->name);
" required.\n");
return -EAGAIN;
} while (0);
}
bp->recovery_state = BNX2X_RECOVERY_DONE;
return bnx2x_nic_load(bp, LOAD_OPEN);
}
......@@ -8920,6 +9337,8 @@ static int bnx2x_close(struct net_device *dev)
/* Unload the driver, release IRQs */
bnx2x_nic_unload(bp, UNLOAD_CLOSE);
/* Power off */
bnx2x_set_power_state(bp, PCI_D3hot);
return 0;
......
......@@ -804,10 +804,12 @@
/* [RW 28] TCM Header when both ULP and TCP context is loaded. */
#define DORQ_REG_SHRT_CMHEAD 0x170054
#define HC_CONFIG_0_REG_ATTN_BIT_EN_0 (0x1<<4)
#define HC_CONFIG_0_REG_BLOCK_DISABLE_0 (0x1<<0)
#define HC_CONFIG_0_REG_INT_LINE_EN_0 (0x1<<3)
#define HC_CONFIG_0_REG_MSI_ATTN_EN_0 (0x1<<7)
#define HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 (0x1<<2)
#define HC_CONFIG_0_REG_SINGLE_ISR_EN_0 (0x1<<1)
#define HC_CONFIG_0_REG_SINGLE_ISR_EN_0 (0x1<<1)
#define HC_CONFIG_1_REG_BLOCK_DISABLE_1 (0x1<<0)
#define HC_REG_AGG_INT_0 0x108050
#define HC_REG_AGG_INT_1 0x108054
#define HC_REG_ATTN_BIT 0x108120
......@@ -846,6 +848,7 @@
#define HC_REG_VQID_0 0x108008
#define HC_REG_VQID_1 0x10800c
#define IGU_BLOCK_CONFIGURATION_REG_BACKWARD_COMP_EN (0x1<<1)
#define IGU_BLOCK_CONFIGURATION_REG_BLOCK_ENABLE (0x1<<0)
#define IGU_REG_ATTENTION_ACK_BITS 0x130108
/* [R 4] Debug: attn_fsm */
#define IGU_REG_ATTN_FSM 0x130054
......@@ -1876,11 +1879,21 @@
/* [R 32] Interrupt register #0 read */
#define NIG_REG_NIG_INT_STS_0 0x103b0
#define NIG_REG_NIG_INT_STS_1 0x103c0
/* [R 32] Legacy E1 and E1H location for parity error mask register. */
#define NIG_REG_NIG_PRTY_MASK 0x103dc
/* [RW 32] Parity mask register #0 read/write */
#define NIG_REG_NIG_PRTY_MASK_0 0x183c8
#define NIG_REG_NIG_PRTY_MASK_1 0x183d8
/* [R 32] Legacy E1 and E1H location for parity error status register. */
#define NIG_REG_NIG_PRTY_STS 0x103d0
/* [R 32] Parity register #0 read */
#define NIG_REG_NIG_PRTY_STS_0 0x183bc
#define NIG_REG_NIG_PRTY_STS_1 0x183cc
/* [R 32] Legacy E1 and E1H location for parity error status clear register. */
#define NIG_REG_NIG_PRTY_STS_CLR 0x103d4
/* [RC 32] Parity register #0 read clear */
#define NIG_REG_NIG_PRTY_STS_CLR_0 0x183c0
#define NIG_REG_NIG_PRTY_STS_CLR_1 0x183d0
/* [RW 6] Bit-map indicating which L2 hdrs may appear after the basic
* Ethernet header. */
#define NIG_REG_P0_HDRS_AFTER_BASIC 0x18038
......@@ -4322,6 +4335,8 @@
#define UCM_REG_UCM_INT_MASK 0xe01d4
/* [R 11] Interrupt register #0 read */
#define UCM_REG_UCM_INT_STS 0xe01c8
/* [RW 27] Parity mask register #0 read/write */
#define UCM_REG_UCM_PRTY_MASK 0xe01e4
/* [R 27] Parity register #0 read */
#define UCM_REG_UCM_PRTY_STS 0xe01d8
/* [RC 27] Parity register #0 read clear */
......@@ -4843,8 +4858,13 @@
#define XCM_REG_XCM_INT_MASK 0x202b4
/* [R 14] Interrupt register #0 read */
#define XCM_REG_XCM_INT_STS 0x202a8
/* [RW 30] Parity mask register #0 read/write */
#define XCM_REG_XCM_PRTY_MASK 0x202c4
/* [R 30] Parity register #0 read */
#define XCM_REG_XCM_PRTY_STS 0x202b8
/* [RC 30] Parity register #0 read clear */
#define XCM_REG_XCM_PRTY_STS_CLR 0x202bc
/* [RW 4] The size of AG context region 0 in REG-pairs. Designates the MS
REG-pair number (e.g. if region 0 is 6 REG-pairs; the value should be 5).
Is used to determine the number of the AG context REG-pairs written back;
......@@ -5284,9 +5304,12 @@
#define MISC_REGISTERS_RESET_REG_2_RST_EMAC1_HARD_CORE (0x1<<15)
#define MISC_REGISTERS_RESET_REG_2_RST_GRC (0x1<<4)
#define MISC_REGISTERS_RESET_REG_2_RST_MCP_N_HARD_CORE_RST_B (0x1<<6)
#define MISC_REGISTERS_RESET_REG_2_RST_MCP_N_RESET_CMN_CORE (0x1<<8)
#define MISC_REGISTERS_RESET_REG_2_RST_MCP_N_RESET_CMN_CPU (0x1<<7)
#define MISC_REGISTERS_RESET_REG_2_RST_MCP_N_RESET_REG_HARD_CORE (0x1<<5)
#define MISC_REGISTERS_RESET_REG_2_RST_MDIO (0x1<<13)
#define MISC_REGISTERS_RESET_REG_2_RST_MISC_CORE (0x1<<11)
#define MISC_REGISTERS_RESET_REG_2_RST_PCI_MDIO (0x1<<13)
#define MISC_REGISTERS_RESET_REG_2_RST_RBCN (0x1<<9)
#define MISC_REGISTERS_RESET_REG_2_SET 0x594
#define MISC_REGISTERS_RESET_REG_3_CLEAR 0x5a8
......@@ -5315,71 +5338,82 @@
#define HW_LOCK_MAX_RESOURCE_VALUE 31
#define HW_LOCK_RESOURCE_GPIO 1
#define HW_LOCK_RESOURCE_MDIO 0
#define HW_LOCK_RESOURCE_PORT0_ATT_MASK 3
#define HW_LOCK_RESOURCE_RESERVED_08 8
#define HW_LOCK_RESOURCE_PORT0_ATT_MASK 3
#define HW_LOCK_RESOURCE_RECOVERY_LEADER_0 8
#define HW_LOCK_RESOURCE_RECOVERY_LEADER_1 9
#define HW_LOCK_RESOURCE_SPIO 2
#define HW_LOCK_RESOURCE_UNDI 5
#define AEU_INPUTS_ATTN_BITS_ATC_HW_INTERRUPT (0x1<<4)
#define AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR (0x1<<5)
#define AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR (1<<18)
#define AEU_INPUTS_ATTN_BITS_CCM_HW_INTERRUPT (1<<31)
#define AEU_INPUTS_ATTN_BITS_CDU_HW_INTERRUPT (1<<9)
#define AEU_INPUTS_ATTN_BITS_CDU_PARITY_ERROR (1<<8)
#define AEU_INPUTS_ATTN_BITS_CFC_HW_INTERRUPT (1<<7)
#define AEU_INPUTS_ATTN_BITS_CFC_PARITY_ERROR (1<<6)
#define AEU_INPUTS_ATTN_BITS_CSDM_HW_INTERRUPT (1<<29)
#define AEU_INPUTS_ATTN_BITS_CSDM_PARITY_ERROR (1<<28)
#define AEU_INPUTS_ATTN_BITS_CSEMI_HW_INTERRUPT (1<<1)
#define AEU_INPUTS_ATTN_BITS_CSEMI_PARITY_ERROR (1<<0)
#define AEU_INPUTS_ATTN_BITS_DEBUG_PARITY_ERROR (1<<18)
#define AEU_INPUTS_ATTN_BITS_DMAE_HW_INTERRUPT (1<<11)
#define AEU_INPUTS_ATTN_BITS_DOORBELLQ_HW_INTERRUPT (1<<13)
#define AEU_INPUTS_ATTN_BITS_DOORBELLQ_PARITY_ERROR (1<<12)
#define AEU_INPUTS_ATTN_BITS_GPIO0_FUNCTION_0 (1<<2)
#define AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 (1<<5)
#define AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 (1<<9)
#define AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR (1<<12)
#define AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY (1<<28)
#define AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY (1<<31)
#define AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY (1<<29)
#define AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY (1<<30)
#define AEU_INPUTS_ATTN_BITS_MISC_HW_INTERRUPT (1<<15)
#define AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR (1<<14)
#define AEU_INPUTS_ATTN_BITS_PARSER_PARITY_ERROR (1<<20)
#define AEU_INPUTS_ATTN_BITS_PBCLIENT_PARITY_ERROR (1<<0)
#define AEU_INPUTS_ATTN_BITS_PBF_HW_INTERRUPT (1<<31)
#define AEU_INPUTS_ATTN_BITS_PGLUE_HW_INTERRUPT (0x1<<2)
#define AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR (0x1<<3)
#define AEU_INPUTS_ATTN_BITS_PXP_HW_INTERRUPT (1<<3)
#define AEU_INPUTS_ATTN_BITS_PXP_PARITY_ERROR (1<<2)
#define AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_HW_INTERRUPT (1<<5)
#define AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR (1<<4)
#define AEU_INPUTS_ATTN_BITS_QM_HW_INTERRUPT (1<<3)
#define AEU_INPUTS_ATTN_BITS_QM_PARITY_ERROR (1<<2)
#define AEU_INPUTS_ATTN_BITS_SEARCHER_PARITY_ERROR (1<<22)
#define AEU_INPUTS_ATTN_BITS_SPIO5 (1<<15)
#define AEU_INPUTS_ATTN_BITS_TCM_HW_INTERRUPT (1<<27)
#define AEU_INPUTS_ATTN_BITS_TIMERS_HW_INTERRUPT (1<<5)
#define AEU_INPUTS_ATTN_BITS_TSDM_HW_INTERRUPT (1<<25)
#define AEU_INPUTS_ATTN_BITS_TSDM_PARITY_ERROR (1<<24)
#define AEU_INPUTS_ATTN_BITS_TSEMI_HW_INTERRUPT (1<<29)
#define AEU_INPUTS_ATTN_BITS_TSEMI_PARITY_ERROR (1<<28)
#define AEU_INPUTS_ATTN_BITS_UCM_HW_INTERRUPT (1<<23)
#define AEU_INPUTS_ATTN_BITS_UPB_HW_INTERRUPT (1<<27)
#define AEU_INPUTS_ATTN_BITS_UPB_PARITY_ERROR (1<<26)
#define AEU_INPUTS_ATTN_BITS_USDM_HW_INTERRUPT (1<<21)
#define AEU_INPUTS_ATTN_BITS_USDM_PARITY_ERROR (1<<20)
#define AEU_INPUTS_ATTN_BITS_USEMI_HW_INTERRUPT (1<<25)
#define AEU_INPUTS_ATTN_BITS_USEMI_PARITY_ERROR (1<<24)
#define AEU_INPUTS_ATTN_BITS_VAUX_PCI_CORE_PARITY_ERROR (1<<16)
#define AEU_INPUTS_ATTN_BITS_XCM_HW_INTERRUPT (1<<9)
#define AEU_INPUTS_ATTN_BITS_XSDM_HW_INTERRUPT (1<<7)
#define AEU_INPUTS_ATTN_BITS_XSDM_PARITY_ERROR (1<<6)
#define AEU_INPUTS_ATTN_BITS_XSEMI_HW_INTERRUPT (1<<11)
#define AEU_INPUTS_ATTN_BITS_XSEMI_PARITY_ERROR (1<<10)
#define AEU_INPUTS_ATTN_BITS_ATC_HW_INTERRUPT (0x1<<4)
#define AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR (0x1<<5)
#define AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR (0x1<<18)
#define AEU_INPUTS_ATTN_BITS_CCM_HW_INTERRUPT (0x1<<31)
#define AEU_INPUTS_ATTN_BITS_CCM_PARITY_ERROR (0x1<<30)
#define AEU_INPUTS_ATTN_BITS_CDU_HW_INTERRUPT (0x1<<9)
#define AEU_INPUTS_ATTN_BITS_CDU_PARITY_ERROR (0x1<<8)
#define AEU_INPUTS_ATTN_BITS_CFC_HW_INTERRUPT (0x1<<7)
#define AEU_INPUTS_ATTN_BITS_CFC_PARITY_ERROR (0x1<<6)
#define AEU_INPUTS_ATTN_BITS_CSDM_HW_INTERRUPT (0x1<<29)
#define AEU_INPUTS_ATTN_BITS_CSDM_PARITY_ERROR (0x1<<28)
#define AEU_INPUTS_ATTN_BITS_CSEMI_HW_INTERRUPT (0x1<<1)
#define AEU_INPUTS_ATTN_BITS_CSEMI_PARITY_ERROR (0x1<<0)
#define AEU_INPUTS_ATTN_BITS_DEBUG_PARITY_ERROR (0x1<<18)
#define AEU_INPUTS_ATTN_BITS_DMAE_HW_INTERRUPT (0x1<<11)
#define AEU_INPUTS_ATTN_BITS_DMAE_PARITY_ERROR (0x1<<10)
#define AEU_INPUTS_ATTN_BITS_DOORBELLQ_HW_INTERRUPT (0x1<<13)
#define AEU_INPUTS_ATTN_BITS_DOORBELLQ_PARITY_ERROR (0x1<<12)
#define AEU_INPUTS_ATTN_BITS_GPIO0_FUNCTION_0 (0x1<<2)
#define AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR (0x1<<12)
#define AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY (0x1<<28)
#define AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY (0x1<<31)
#define AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY (0x1<<29)
#define AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY (0x1<<30)
#define AEU_INPUTS_ATTN_BITS_MISC_HW_INTERRUPT (0x1<<15)
#define AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR (0x1<<14)
#define AEU_INPUTS_ATTN_BITS_NIG_PARITY_ERROR (0x1<<14)
#define AEU_INPUTS_ATTN_BITS_PARSER_PARITY_ERROR (0x1<<20)
#define AEU_INPUTS_ATTN_BITS_PBCLIENT_HW_INTERRUPT (0x1<<31)
#define AEU_INPUTS_ATTN_BITS_PBCLIENT_PARITY_ERROR (0x1<<30)
#define AEU_INPUTS_ATTN_BITS_PBF_PARITY_ERROR (0x1<<0)
#define AEU_INPUTS_ATTN_BITS_PGLUE_HW_INTERRUPT (0x1<<2)
#define AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR (0x1<<3)
#define AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_HW_INTERRUPT (0x1<<5)
#define AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR (0x1<<4)
#define AEU_INPUTS_ATTN_BITS_PXP_HW_INTERRUPT (0x1<<3)
#define AEU_INPUTS_ATTN_BITS_PXP_PARITY_ERROR (0x1<<2)
#define AEU_INPUTS_ATTN_BITS_QM_HW_INTERRUPT (0x1<<3)
#define AEU_INPUTS_ATTN_BITS_QM_PARITY_ERROR (0x1<<2)
#define AEU_INPUTS_ATTN_BITS_SEARCHER_PARITY_ERROR (0x1<<22)
#define AEU_INPUTS_ATTN_BITS_SPIO5 (0x1<<15)
#define AEU_INPUTS_ATTN_BITS_TCM_HW_INTERRUPT (0x1<<27)
#define AEU_INPUTS_ATTN_BITS_TCM_PARITY_ERROR (0x1<<26)
#define AEU_INPUTS_ATTN_BITS_TIMERS_HW_INTERRUPT (0x1<<5)
#define AEU_INPUTS_ATTN_BITS_TIMERS_PARITY_ERROR (0x1<<4)
#define AEU_INPUTS_ATTN_BITS_TSDM_HW_INTERRUPT (0x1<<25)
#define AEU_INPUTS_ATTN_BITS_TSDM_PARITY_ERROR (0x1<<24)
#define AEU_INPUTS_ATTN_BITS_TSEMI_HW_INTERRUPT (0x1<<29)
#define AEU_INPUTS_ATTN_BITS_TSEMI_PARITY_ERROR (0x1<<28)
#define AEU_INPUTS_ATTN_BITS_UCM_HW_INTERRUPT (0x1<<23)
#define AEU_INPUTS_ATTN_BITS_UCM_PARITY_ERROR (0x1<<22)
#define AEU_INPUTS_ATTN_BITS_UPB_HW_INTERRUPT (0x1<<27)
#define AEU_INPUTS_ATTN_BITS_UPB_PARITY_ERROR (0x1<<26)
#define AEU_INPUTS_ATTN_BITS_USDM_HW_INTERRUPT (0x1<<21)
#define AEU_INPUTS_ATTN_BITS_USDM_PARITY_ERROR (0x1<<20)
#define AEU_INPUTS_ATTN_BITS_USEMI_HW_INTERRUPT (0x1<<25)
#define AEU_INPUTS_ATTN_BITS_USEMI_PARITY_ERROR (0x1<<24)
#define AEU_INPUTS_ATTN_BITS_VAUX_PCI_CORE_PARITY_ERROR (0x1<<16)
#define AEU_INPUTS_ATTN_BITS_XCM_HW_INTERRUPT (0x1<<9)
#define AEU_INPUTS_ATTN_BITS_XCM_PARITY_ERROR (0x1<<8)
#define AEU_INPUTS_ATTN_BITS_XSDM_HW_INTERRUPT (0x1<<7)
#define AEU_INPUTS_ATTN_BITS_XSDM_PARITY_ERROR (0x1<<6)
#define AEU_INPUTS_ATTN_BITS_XSEMI_HW_INTERRUPT (0x1<<11)
#define AEU_INPUTS_ATTN_BITS_XSEMI_PARITY_ERROR (0x1<<10)
#define AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 (0x1<<5)
#define AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 (0x1<<9)
#define RESERVED_GENERAL_ATTENTION_BIT_0 0
#define EVEREST_GEN_ATTN_IN_USE_MASK 0x3ffe0
#define EVEREST_GEN_ATTN_IN_USE_MASK 0x7ffe0
#define EVEREST_LATCHED_ATTN_IN_USE_MASK 0xffe00000
#define RESERVED_GENERAL_ATTENTION_BIT_6 6
......
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