Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

cxgb4: handle interrupt raised when FW crashes

Handle TIMER0INT when FW crashes. Check for PCIE_FW[FW_EVAL]
and if it says "Device FW Crashed", then treat it as fatal.
Else, non-fatal.

Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Rahul Lakkireddy and committed by
David S. Miller
d86cc04e 9438d27a

+26 -1
+18 -1
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
··· 4040 4040 { MBHOSTPARERR_F, "CIM mailbox host parity error", -1, 1 }, 4041 4041 { TIEQINPARERRINT_F, "CIM TIEQ outgoing parity error", -1, 1 }, 4042 4042 { TIEQOUTPARERRINT_F, "CIM TIEQ incoming parity error", -1, 1 }, 4043 + { TIMER0INT_F, "CIM TIMER0 interrupt", -1, 1 }, 4043 4044 { 0 } 4044 4045 }; 4045 4046 static const struct intr_info cim_upintr_info[] = { ··· 4075 4074 { 0 } 4076 4075 }; 4077 4076 4077 + u32 val, fw_err; 4078 4078 int fat; 4079 4079 4080 - if (t4_read_reg(adapter, PCIE_FW_A) & PCIE_FW_ERR_F) 4080 + fw_err = t4_read_reg(adapter, PCIE_FW_A); 4081 + if (fw_err & PCIE_FW_ERR_F) 4081 4082 t4_report_fw_error(adapter); 4083 + 4084 + /* When the Firmware detects an internal error which normally 4085 + * wouldn't raise a Host Interrupt, it forces a CIM Timer0 interrupt 4086 + * in order to make sure the Host sees the Firmware Crash. So 4087 + * if we have a Timer0 interrupt and don't see a Firmware Crash, 4088 + * ignore the Timer0 interrupt. 4089 + */ 4090 + 4091 + val = t4_read_reg(adapter, CIM_HOST_INT_CAUSE_A); 4092 + if (val & TIMER0INT_F) 4093 + if (!(fw_err & PCIE_FW_ERR_F) || 4094 + (PCIE_FW_EVAL_G(fw_err) != PCIE_FW_EVAL_CRASH)) 4095 + t4_write_reg(adapter, CIM_HOST_INT_CAUSE_A, 4096 + TIMER0INT_F); 4082 4097 4083 4098 fat = t4_handle_intr_status(adapter, CIM_HOST_INT_CAUSE_A, 4084 4099 cim_intr_info) +
+4
drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
··· 1077 1077 #define TIEQINPARERRINT_V(x) ((x) << TIEQINPARERRINT_S) 1078 1078 #define TIEQINPARERRINT_F TIEQINPARERRINT_V(1U) 1079 1079 1080 + #define TIMER0INT_S 2 1081 + #define TIMER0INT_V(x) ((x) << TIMER0INT_S) 1082 + #define TIMER0INT_F TIMER0INT_V(1U) 1083 + 1080 1084 #define PREFDROPINT_S 1 1081 1085 #define PREFDROPINT_V(x) ((x) << PREFDROPINT_S) 1082 1086 #define PREFDROPINT_F PREFDROPINT_V(1U)
+4
drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
··· 3088 3088 #define FW_DEBUG_CMD_TYPE_G(x) \ 3089 3089 (((x) >> FW_DEBUG_CMD_TYPE_S) & FW_DEBUG_CMD_TYPE_M) 3090 3090 3091 + enum pcie_fw_eval { 3092 + PCIE_FW_EVAL_CRASH = 0, 3093 + }; 3094 + 3091 3095 #define PCIE_FW_ERR_S 31 3092 3096 #define PCIE_FW_ERR_V(x) ((x) << PCIE_FW_ERR_S) 3093 3097 #define PCIE_FW_ERR_F PCIE_FW_ERR_V(1U)