scsi: hisi_sas: add v2 hw support for ECC and AXI bus fatal error

For ECC 1bit error, logic can recover it, so we only print
a warning.
For ECC multi-bit and AXI bus fatal error, we panic.

Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
Signed-off-by: John Garry <john.garry@huawei.com>
Reviewed-by: Zhangfei Gao <zhangfei.gao@linaro.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Xiang Chen 2016-11-07 20:48:30 +08:00 committed by Martin K. Petersen
parent 2d76a2478b
commit d3b688d3c6
1 changed files with 420 additions and 5 deletions

View File

@ -55,10 +55,44 @@
#define HGC_DFX_CFG2 0xc0
#define HGC_IOMB_PROC1_STATUS 0x104
#define CFG_1US_TIMER_TRSH 0xcc
#define HGC_LM_DFX_STATUS2 0x128
#define HGC_LM_DFX_STATUS2_IOSTLIST_OFF 0
#define HGC_LM_DFX_STATUS2_IOSTLIST_MSK (0xfff << \
HGC_LM_DFX_STATUS2_IOSTLIST_OFF)
#define HGC_LM_DFX_STATUS2_ITCTLIST_OFF 12
#define HGC_LM_DFX_STATUS2_ITCTLIST_MSK (0x7ff << \
HGC_LM_DFX_STATUS2_ITCTLIST_OFF)
#define HGC_CQE_ECC_ADDR 0x13c
#define HGC_CQE_ECC_1B_ADDR_OFF 0
#define HGC_CQE_ECC_1B_ADDR_MSK (0x3f < HGC_CQE_ECC_1B_ADDR_OFF)
#define HGC_CQE_ECC_MB_ADDR_OFF 8
#define HGC_CQE_ECC_MB_ADDR_MSK (0x3f < HGC_CQE_ECC_MB_ADDR_OFF)
#define HGC_IOST_ECC_ADDR 0x140
#define HGC_IOST_ECC_1B_ADDR_OFF 0
#define HGC_IOST_ECC_1B_ADDR_MSK (0x3ff < HGC_IOST_ECC_1B_ADDR_OFF)
#define HGC_IOST_ECC_MB_ADDR_OFF 16
#define HGC_IOST_ECC_MB_ADDR_MSK (0x3ff < HGC_IOST_ECC_MB_ADDR_OFF)
#define HGC_DQE_ECC_ADDR 0x144
#define HGC_DQE_ECC_1B_ADDR_OFF 0
#define HGC_DQE_ECC_1B_ADDR_MSK (0xfff < HGC_DQE_ECC_1B_ADDR_OFF)
#define HGC_DQE_ECC_MB_ADDR_OFF 16
#define HGC_DQE_ECC_MB_ADDR_MSK (0xfff < HGC_DQE_ECC_MB_ADDR_OFF)
#define HGC_INVLD_DQE_INFO 0x148
#define HGC_INVLD_DQE_INFO_FB_CH0_OFF 9
#define HGC_INVLD_DQE_INFO_FB_CH0_MSK (0x1 << HGC_INVLD_DQE_INFO_FB_CH0_OFF)
#define HGC_INVLD_DQE_INFO_FB_CH3_OFF 18
#define HGC_ITCT_ECC_ADDR 0x150
#define HGC_ITCT_ECC_1B_ADDR_OFF 0
#define HGC_ITCT_ECC_1B_ADDR_MSK (0x3ff << \
HGC_ITCT_ECC_1B_ADDR_OFF)
#define HGC_ITCT_ECC_MB_ADDR_OFF 16
#define HGC_ITCT_ECC_MB_ADDR_MSK (0x3ff << \
HGC_ITCT_ECC_MB_ADDR_OFF)
#define HGC_AXI_FIFO_ERR_INFO 0x154
#define AXI_ERR_INFO_OFF 0
#define AXI_ERR_INFO_MSK (0xff << AXI_ERR_INFO_OFF)
#define FIFO_ERR_INFO_OFF 8
#define FIFO_ERR_INFO_MSK (0xff << FIFO_ERR_INFO_OFF)
#define INT_COAL_EN 0x19c
#define OQ_INT_COAL_TIME 0x1a0
#define OQ_INT_COAL_CNT 0x1a4
@ -73,13 +107,41 @@
#define ENT_INT_SRC1_D2H_FIS_CH1_MSK (0x1 << ENT_INT_SRC1_D2H_FIS_CH1_OFF)
#define ENT_INT_SRC2 0x1bc
#define ENT_INT_SRC3 0x1c0
#define ENT_INT_SRC3_WP_DEPTH_OFF 8
#define ENT_INT_SRC3_IPTT_SLOT_NOMATCH_OFF 9
#define ENT_INT_SRC3_RP_DEPTH_OFF 10
#define ENT_INT_SRC3_AXI_OFF 11
#define ENT_INT_SRC3_FIFO_OFF 12
#define ENT_INT_SRC3_LM_OFF 14
#define ENT_INT_SRC3_ITC_INT_OFF 15
#define ENT_INT_SRC3_ITC_INT_MSK (0x1 << ENT_INT_SRC3_ITC_INT_OFF)
#define ENT_INT_SRC3_ABT_OFF 16
#define ENT_INT_SRC_MSK1 0x1c4
#define ENT_INT_SRC_MSK2 0x1c8
#define ENT_INT_SRC_MSK3 0x1cc
#define ENT_INT_SRC_MSK3_ENT95_MSK_OFF 31
#define ENT_INT_SRC_MSK3_ENT95_MSK_MSK (0x1 << ENT_INT_SRC_MSK3_ENT95_MSK_OFF)
#define SAS_ECC_INTR 0x1e8
#define SAS_ECC_INTR_DQE_ECC_1B_OFF 0
#define SAS_ECC_INTR_DQE_ECC_MB_OFF 1
#define SAS_ECC_INTR_IOST_ECC_1B_OFF 2
#define SAS_ECC_INTR_IOST_ECC_MB_OFF 3
#define SAS_ECC_INTR_ITCT_ECC_MB_OFF 4
#define SAS_ECC_INTR_ITCT_ECC_1B_OFF 5
#define SAS_ECC_INTR_IOSTLIST_ECC_MB_OFF 6
#define SAS_ECC_INTR_IOSTLIST_ECC_1B_OFF 7
#define SAS_ECC_INTR_ITCTLIST_ECC_1B_OFF 8
#define SAS_ECC_INTR_ITCTLIST_ECC_MB_OFF 9
#define SAS_ECC_INTR_CQE_ECC_1B_OFF 10
#define SAS_ECC_INTR_CQE_ECC_MB_OFF 11
#define SAS_ECC_INTR_NCQ_MEM0_ECC_MB_OFF 12
#define SAS_ECC_INTR_NCQ_MEM0_ECC_1B_OFF 13
#define SAS_ECC_INTR_NCQ_MEM1_ECC_MB_OFF 14
#define SAS_ECC_INTR_NCQ_MEM1_ECC_1B_OFF 15
#define SAS_ECC_INTR_NCQ_MEM2_ECC_MB_OFF 16
#define SAS_ECC_INTR_NCQ_MEM2_ECC_1B_OFF 17
#define SAS_ECC_INTR_NCQ_MEM3_ECC_MB_OFF 18
#define SAS_ECC_INTR_NCQ_MEM3_ECC_1B_OFF 19
#define SAS_ECC_INTR_MSK 0x1ec
#define HGC_ERR_STAT_EN 0x238
#define DLVRY_Q_0_BASE_ADDR_LO 0x260
@ -94,7 +156,20 @@
#define COMPL_Q_0_DEPTH 0x4e8
#define COMPL_Q_0_WR_PTR 0x4ec
#define COMPL_Q_0_RD_PTR 0x4f0
#define HGC_RXM_DFX_STATUS14 0xae8
#define HGC_RXM_DFX_STATUS14_MEM0_OFF 0
#define HGC_RXM_DFX_STATUS14_MEM0_MSK (0x1ff << \
HGC_RXM_DFX_STATUS14_MEM0_OFF)
#define HGC_RXM_DFX_STATUS14_MEM1_OFF 9
#define HGC_RXM_DFX_STATUS14_MEM1_MSK (0x1ff << \
HGC_RXM_DFX_STATUS14_MEM1_OFF)
#define HGC_RXM_DFX_STATUS14_MEM2_OFF 18
#define HGC_RXM_DFX_STATUS14_MEM2_MSK (0x1ff << \
HGC_RXM_DFX_STATUS14_MEM2_OFF)
#define HGC_RXM_DFX_STATUS15 0xaec
#define HGC_RXM_DFX_STATUS15_MEM3_OFF 0
#define HGC_RXM_DFX_STATUS15_MEM3_MSK (0x1ff << \
HGC_RXM_DFX_STATUS15_MEM3_OFF)
/* phy registers need init */
#define PORT_BASE (0x2000)
@ -267,6 +342,8 @@
#define ITCT_HDR_RTOLT_OFF 48
#define ITCT_HDR_RTOLT_MSK (0xffffULL << ITCT_HDR_RTOLT_OFF)
#define HISI_SAS_FATAL_INT_NR 2
struct hisi_sas_complete_v2_hdr {
__le32 dw0;
__le32 dw1;
@ -808,7 +885,7 @@ static void init_reg_v2_hw(struct hisi_hba *hisi_hba)
hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, 0x7efefefe);
hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK2, 0x7efefefe);
hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0x7ffffffe);
hisi_sas_write32(hisi_hba, SAS_ECC_INTR_MSK, 0xfffff3c0);
hisi_sas_write32(hisi_hba, SAS_ECC_INTR_MSK, 0xfff00c30);
for (i = 0; i < hisi_hba->queue_count; i++)
hisi_sas_write32(hisi_hba, OQ0_INT_SRC_MSK+0x4*i, 0);
@ -824,7 +901,7 @@ static void init_reg_v2_hw(struct hisi_hba *hisi_hba)
hisi_sas_phy_write32(hisi_hba, i, DONE_RECEIVED_TIME, 0x10);
hisi_sas_phy_write32(hisi_hba, i, CHL_INT0, 0xffffffff);
hisi_sas_phy_write32(hisi_hba, i, CHL_INT1, 0xffffffff);
hisi_sas_phy_write32(hisi_hba, i, CHL_INT2, 0xffffffff);
hisi_sas_phy_write32(hisi_hba, i, CHL_INT2, 0xfff87fff);
hisi_sas_phy_write32(hisi_hba, i, RXOP_CHECK_CFG_H, 0x1000);
hisi_sas_phy_write32(hisi_hba, i, CHL_INT1_MSK, 0xffffffff);
hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0x8ffffbff);
@ -2007,8 +2084,9 @@ static irqreturn_t int_chnl_int_v2_hw(int irq_no, void *p)
if (irq_value1) {
if (irq_value1 & (CHL_INT1_DMAC_RX_ECC_ERR_MSK |
CHL_INT1_DMAC_TX_ECC_ERR_MSK))
panic("%s: DMAC RX/TX ecc bad error! (0x%x)",
dev_name(dev), irq_value1);
panic("%s: DMAC RX/TX ecc bad error!\
(0x%x)",
dev_name(dev), irq_value1);
hisi_sas_phy_write32(hisi_hba, phy_no,
CHL_INT1, irq_value1);
@ -2039,6 +2117,318 @@ static irqreturn_t int_chnl_int_v2_hw(int irq_no, void *p)
return IRQ_HANDLED;
}
static void
one_bit_ecc_error_process_v2_hw(struct hisi_hba *hisi_hba, u32 irq_value)
{
struct device *dev = &hisi_hba->pdev->dev;
u32 reg_val;
if (irq_value & BIT(SAS_ECC_INTR_DQE_ECC_1B_OFF)) {
reg_val = hisi_sas_read32(hisi_hba, HGC_DQE_ECC_ADDR);
dev_warn(dev, "hgc_dqe_acc1b_intr found: \
Ram address is 0x%08X\n",
(reg_val & HGC_DQE_ECC_1B_ADDR_MSK) >>
HGC_DQE_ECC_1B_ADDR_OFF);
}
if (irq_value & BIT(SAS_ECC_INTR_IOST_ECC_1B_OFF)) {
reg_val = hisi_sas_read32(hisi_hba, HGC_IOST_ECC_ADDR);
dev_warn(dev, "hgc_iost_acc1b_intr found: \
Ram address is 0x%08X\n",
(reg_val & HGC_IOST_ECC_1B_ADDR_MSK) >>
HGC_IOST_ECC_1B_ADDR_OFF);
}
if (irq_value & BIT(SAS_ECC_INTR_ITCT_ECC_1B_OFF)) {
reg_val = hisi_sas_read32(hisi_hba, HGC_ITCT_ECC_ADDR);
dev_warn(dev, "hgc_itct_acc1b_intr found: \
Ram address is 0x%08X\n",
(reg_val & HGC_ITCT_ECC_1B_ADDR_MSK) >>
HGC_ITCT_ECC_1B_ADDR_OFF);
}
if (irq_value & BIT(SAS_ECC_INTR_IOSTLIST_ECC_1B_OFF)) {
reg_val = hisi_sas_read32(hisi_hba, HGC_LM_DFX_STATUS2);
dev_warn(dev, "hgc_iostl_acc1b_intr found: \
memory address is 0x%08X\n",
(reg_val & HGC_LM_DFX_STATUS2_IOSTLIST_MSK) >>
HGC_LM_DFX_STATUS2_IOSTLIST_OFF);
}
if (irq_value & BIT(SAS_ECC_INTR_ITCTLIST_ECC_1B_OFF)) {
reg_val = hisi_sas_read32(hisi_hba, HGC_LM_DFX_STATUS2);
dev_warn(dev, "hgc_itctl_acc1b_intr found: \
memory address is 0x%08X\n",
(reg_val & HGC_LM_DFX_STATUS2_ITCTLIST_MSK) >>
HGC_LM_DFX_STATUS2_ITCTLIST_OFF);
}
if (irq_value & BIT(SAS_ECC_INTR_CQE_ECC_1B_OFF)) {
reg_val = hisi_sas_read32(hisi_hba, HGC_CQE_ECC_ADDR);
dev_warn(dev, "hgc_cqe_acc1b_intr found: \
Ram address is 0x%08X\n",
(reg_val & HGC_CQE_ECC_1B_ADDR_MSK) >>
HGC_CQE_ECC_1B_ADDR_OFF);
}
if (irq_value & BIT(SAS_ECC_INTR_NCQ_MEM0_ECC_1B_OFF)) {
reg_val = hisi_sas_read32(hisi_hba, HGC_RXM_DFX_STATUS14);
dev_warn(dev, "rxm_mem0_acc1b_intr found: \
memory address is 0x%08X\n",
(reg_val & HGC_RXM_DFX_STATUS14_MEM0_MSK) >>
HGC_RXM_DFX_STATUS14_MEM0_OFF);
}
if (irq_value & BIT(SAS_ECC_INTR_NCQ_MEM1_ECC_1B_OFF)) {
reg_val = hisi_sas_read32(hisi_hba, HGC_RXM_DFX_STATUS14);
dev_warn(dev, "rxm_mem1_acc1b_intr found: \
memory address is 0x%08X\n",
(reg_val & HGC_RXM_DFX_STATUS14_MEM1_MSK) >>
HGC_RXM_DFX_STATUS14_MEM1_OFF);
}
if (irq_value & BIT(SAS_ECC_INTR_NCQ_MEM2_ECC_1B_OFF)) {
reg_val = hisi_sas_read32(hisi_hba, HGC_RXM_DFX_STATUS14);
dev_warn(dev, "rxm_mem2_acc1b_intr found: \
memory address is 0x%08X\n",
(reg_val & HGC_RXM_DFX_STATUS14_MEM2_MSK) >>
HGC_RXM_DFX_STATUS14_MEM2_OFF);
}
if (irq_value & BIT(SAS_ECC_INTR_NCQ_MEM3_ECC_1B_OFF)) {
reg_val = hisi_sas_read32(hisi_hba, HGC_RXM_DFX_STATUS15);
dev_warn(dev, "rxm_mem3_acc1b_intr found: \
memory address is 0x%08X\n",
(reg_val & HGC_RXM_DFX_STATUS15_MEM3_MSK) >>
HGC_RXM_DFX_STATUS15_MEM3_OFF);
}
}
static void multi_bit_ecc_error_process_v2_hw(struct hisi_hba *hisi_hba,
u32 irq_value)
{
u32 reg_val;
struct device *dev = &hisi_hba->pdev->dev;
if (irq_value & BIT(SAS_ECC_INTR_DQE_ECC_MB_OFF)) {
reg_val = hisi_sas_read32(hisi_hba, HGC_DQE_ECC_ADDR);
panic("%s: hgc_dqe_accbad_intr (0x%x) found: \
Ram address is 0x%08X\n",
dev_name(dev), irq_value,
(reg_val & HGC_DQE_ECC_MB_ADDR_MSK) >>
HGC_DQE_ECC_MB_ADDR_OFF);
}
if (irq_value & BIT(SAS_ECC_INTR_IOST_ECC_MB_OFF)) {
reg_val = hisi_sas_read32(hisi_hba, HGC_IOST_ECC_ADDR);
panic("%s: hgc_iost_accbad_intr (0x%x) found: \
Ram address is 0x%08X\n",
dev_name(dev), irq_value,
(reg_val & HGC_IOST_ECC_MB_ADDR_MSK) >>
HGC_IOST_ECC_MB_ADDR_OFF);
}
if (irq_value & BIT(SAS_ECC_INTR_ITCT_ECC_MB_OFF)) {
reg_val = hisi_sas_read32(hisi_hba, HGC_ITCT_ECC_ADDR);
panic("%s: hgc_itct_accbad_intr (0x%x) found: \
Ram address is 0x%08X\n",
dev_name(dev), irq_value,
(reg_val & HGC_ITCT_ECC_MB_ADDR_MSK) >>
HGC_ITCT_ECC_MB_ADDR_OFF);
}
if (irq_value & BIT(SAS_ECC_INTR_IOSTLIST_ECC_MB_OFF)) {
reg_val = hisi_sas_read32(hisi_hba, HGC_LM_DFX_STATUS2);
panic("%s: hgc_iostl_accbad_intr (0x%x) found: \
memory address is 0x%08X\n",
dev_name(dev), irq_value,
(reg_val & HGC_LM_DFX_STATUS2_IOSTLIST_MSK) >>
HGC_LM_DFX_STATUS2_IOSTLIST_OFF);
}
if (irq_value & BIT(SAS_ECC_INTR_ITCTLIST_ECC_MB_OFF)) {
reg_val = hisi_sas_read32(hisi_hba, HGC_LM_DFX_STATUS2);
panic("%s: hgc_itctl_accbad_intr (0x%x) found: \
memory address is 0x%08X\n",
dev_name(dev), irq_value,
(reg_val & HGC_LM_DFX_STATUS2_ITCTLIST_MSK) >>
HGC_LM_DFX_STATUS2_ITCTLIST_OFF);
}
if (irq_value & BIT(SAS_ECC_INTR_CQE_ECC_MB_OFF)) {
reg_val = hisi_sas_read32(hisi_hba, HGC_CQE_ECC_ADDR);
panic("%s: hgc_cqe_accbad_intr (0x%x) found: \
Ram address is 0x%08X\n",
dev_name(dev), irq_value,
(reg_val & HGC_CQE_ECC_MB_ADDR_MSK) >>
HGC_CQE_ECC_MB_ADDR_OFF);
}
if (irq_value & BIT(SAS_ECC_INTR_NCQ_MEM0_ECC_MB_OFF)) {
reg_val = hisi_sas_read32(hisi_hba, HGC_RXM_DFX_STATUS14);
panic("%s: rxm_mem0_accbad_intr (0x%x) found: \
memory address is 0x%08X\n",
dev_name(dev), irq_value,
(reg_val & HGC_RXM_DFX_STATUS14_MEM0_MSK) >>
HGC_RXM_DFX_STATUS14_MEM0_OFF);
}
if (irq_value & BIT(SAS_ECC_INTR_NCQ_MEM1_ECC_MB_OFF)) {
reg_val = hisi_sas_read32(hisi_hba, HGC_RXM_DFX_STATUS14);
panic("%s: rxm_mem1_accbad_intr (0x%x) found: \
memory address is 0x%08X\n",
dev_name(dev), irq_value,
(reg_val & HGC_RXM_DFX_STATUS14_MEM1_MSK) >>
HGC_RXM_DFX_STATUS14_MEM1_OFF);
}
if (irq_value & BIT(SAS_ECC_INTR_NCQ_MEM2_ECC_MB_OFF)) {
reg_val = hisi_sas_read32(hisi_hba, HGC_RXM_DFX_STATUS14);
panic("%s: rxm_mem2_accbad_intr (0x%x) found: \
memory address is 0x%08X\n",
dev_name(dev), irq_value,
(reg_val & HGC_RXM_DFX_STATUS14_MEM2_MSK) >>
HGC_RXM_DFX_STATUS14_MEM2_OFF);
}
if (irq_value & BIT(SAS_ECC_INTR_NCQ_MEM3_ECC_MB_OFF)) {
reg_val = hisi_sas_read32(hisi_hba, HGC_RXM_DFX_STATUS15);
panic("%s: rxm_mem3_accbad_intr (0x%x) found: \
memory address is 0x%08X\n",
dev_name(dev), irq_value,
(reg_val & HGC_RXM_DFX_STATUS15_MEM3_MSK) >>
HGC_RXM_DFX_STATUS15_MEM3_OFF);
}
}
static irqreturn_t fatal_ecc_int_v2_hw(int irq_no, void *p)
{
struct hisi_hba *hisi_hba = p;
u32 irq_value, irq_msk;
irq_msk = hisi_sas_read32(hisi_hba, SAS_ECC_INTR_MSK);
hisi_sas_write32(hisi_hba, SAS_ECC_INTR_MSK, irq_msk | 0xffffffff);
irq_value = hisi_sas_read32(hisi_hba, SAS_ECC_INTR);
if (irq_value) {
one_bit_ecc_error_process_v2_hw(hisi_hba, irq_value);
multi_bit_ecc_error_process_v2_hw(hisi_hba, irq_value);
}
hisi_sas_write32(hisi_hba, SAS_ECC_INTR, irq_value);
hisi_sas_write32(hisi_hba, SAS_ECC_INTR_MSK, irq_msk);
return IRQ_HANDLED;
}
#define AXI_ERR_NR 8
static const char axi_err_info[AXI_ERR_NR][32] = {
"IOST_AXI_W_ERR",
"IOST_AXI_R_ERR",
"ITCT_AXI_W_ERR",
"ITCT_AXI_R_ERR",
"SATA_AXI_W_ERR",
"SATA_AXI_R_ERR",
"DQE_AXI_R_ERR",
"CQE_AXI_W_ERR"
};
#define FIFO_ERR_NR 5
static const char fifo_err_info[FIFO_ERR_NR][32] = {
"CQE_WINFO_FIFO",
"CQE_MSG_FIFIO",
"GETDQE_FIFO",
"CMDP_FIFO",
"AWTCTRL_FIFO"
};
static irqreturn_t fatal_axi_int_v2_hw(int irq_no, void *p)
{
struct hisi_hba *hisi_hba = p;
u32 irq_value, irq_msk, err_value;
struct device *dev = &hisi_hba->pdev->dev;
irq_msk = hisi_sas_read32(hisi_hba, ENT_INT_SRC_MSK3);
hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, irq_msk | 0xfffffffe);
irq_value = hisi_sas_read32(hisi_hba, ENT_INT_SRC3);
if (irq_value) {
if (irq_value & BIT(ENT_INT_SRC3_WP_DEPTH_OFF)) {
hisi_sas_write32(hisi_hba, ENT_INT_SRC3,
1 << ENT_INT_SRC3_WP_DEPTH_OFF);
panic("%s: write pointer and depth error (0x%x) \
found!\n",
dev_name(dev), irq_value);
}
if (irq_value & BIT(ENT_INT_SRC3_IPTT_SLOT_NOMATCH_OFF)) {
hisi_sas_write32(hisi_hba, ENT_INT_SRC3,
1 <<
ENT_INT_SRC3_IPTT_SLOT_NOMATCH_OFF);
panic("%s: iptt no match slot error (0x%x) found!\n",
dev_name(dev), irq_value);
}
if (irq_value & BIT(ENT_INT_SRC3_RP_DEPTH_OFF))
panic("%s: read pointer and depth error (0x%x) \
found!\n",
dev_name(dev), irq_value);
if (irq_value & BIT(ENT_INT_SRC3_AXI_OFF)) {
int i;
hisi_sas_write32(hisi_hba, ENT_INT_SRC3,
1 << ENT_INT_SRC3_AXI_OFF);
err_value = hisi_sas_read32(hisi_hba,
HGC_AXI_FIFO_ERR_INFO);
for (i = 0; i < AXI_ERR_NR; i++) {
if (err_value & BIT(i))
panic("%s: %s (0x%x) found!\n",
dev_name(dev),
axi_err_info[i], irq_value);
}
}
if (irq_value & BIT(ENT_INT_SRC3_FIFO_OFF)) {
int i;
hisi_sas_write32(hisi_hba, ENT_INT_SRC3,
1 << ENT_INT_SRC3_FIFO_OFF);
err_value = hisi_sas_read32(hisi_hba,
HGC_AXI_FIFO_ERR_INFO);
for (i = 0; i < FIFO_ERR_NR; i++) {
if (err_value & BIT(AXI_ERR_NR + i))
panic("%s: %s (0x%x) found!\n",
dev_name(dev),
fifo_err_info[i], irq_value);
}
}
if (irq_value & BIT(ENT_INT_SRC3_LM_OFF)) {
hisi_sas_write32(hisi_hba, ENT_INT_SRC3,
1 << ENT_INT_SRC3_LM_OFF);
panic("%s: LM add/fetch list error (0x%x) found!\n",
dev_name(dev), irq_value);
}
if (irq_value & BIT(ENT_INT_SRC3_ABT_OFF)) {
hisi_sas_write32(hisi_hba, ENT_INT_SRC3,
1 << ENT_INT_SRC3_ABT_OFF);
panic("%s: SAS_HGC_ABT fetch LM list error (0x%x) found!\n",
dev_name(dev), irq_value);
}
}
hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, irq_msk);
return IRQ_HANDLED;
}
static irqreturn_t cq_interrupt_v2_hw(int irq_no, void *p)
{
struct hisi_sas_cq *cq = p;
@ -2192,6 +2582,11 @@ static irq_handler_t phy_interrupts[HISI_SAS_PHY_INT_NR] = {
int_chnl_int_v2_hw,
};
static irq_handler_t fatal_interrupts[HISI_SAS_FATAL_INT_NR] = {
fatal_ecc_int_v2_hw,
fatal_axi_int_v2_hw
};
/**
* There is a limitation in the hip06 chipset that we need
* to map in all mbigen interrupts, even if they are not used.
@ -2247,6 +2642,26 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba)
}
}
for (i = 0; i < HISI_SAS_FATAL_INT_NR; i++) {
int idx = i;
irq = irq_map[idx + 81];
if (!irq) {
dev_err(dev, "irq init: fail map fatal interrupt %d\n",
idx);
return -ENOENT;
}
rc = devm_request_irq(dev, irq, fatal_interrupts[i], 0,
DRV_NAME " fatal", hisi_hba);
if (rc) {
dev_err(dev,
"irq init: could not request fatal interrupt %d, rc=%d\n",
irq, rc);
return -ENOENT;
}
}
for (i = 0; i < hisi_hba->queue_count; i++) {
int idx = i + 96; /* First cq interrupt is irq96 */