| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (c) 2017 Hisilicon Limited. |
|---|
| 3 | | - * |
|---|
| 4 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 5 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 6 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 7 | | - * (at your option) any later version. |
|---|
| 8 | | - * |
|---|
| 9 | 4 | */ |
|---|
| 10 | 5 | |
|---|
| 11 | 6 | #include "hisi_sas.h" |
|---|
| 12 | 7 | #define DRV_NAME "hisi_sas_v3_hw" |
|---|
| 13 | 8 | |
|---|
| 14 | | -/* global registers need init*/ |
|---|
| 9 | +/* global registers need init */ |
|---|
| 15 | 10 | #define DLVRY_QUEUE_ENABLE 0x0 |
|---|
| 16 | 11 | #define IOST_BASE_ADDR_LO 0x8 |
|---|
| 17 | 12 | #define IOST_BASE_ADDR_HI 0xc |
|---|
| .. | .. |
|---|
| 28 | 23 | #define ITCT_CLR_EN_MSK (0x1 << ITCT_CLR_EN_OFF) |
|---|
| 29 | 24 | #define ITCT_DEV_OFF 0 |
|---|
| 30 | 25 | #define ITCT_DEV_MSK (0x7ff << ITCT_DEV_OFF) |
|---|
| 26 | +#define SAS_AXI_USER3 0x50 |
|---|
| 31 | 27 | #define IO_SATA_BROKEN_MSG_ADDR_LO 0x58 |
|---|
| 32 | 28 | #define IO_SATA_BROKEN_MSG_ADDR_HI 0x5c |
|---|
| 33 | 29 | #define SATA_INITI_D2H_STORE_ADDR_LO 0x60 |
|---|
| .. | .. |
|---|
| 42 | 38 | #define MAX_CON_TIME_LIMIT_TIME 0xa4 |
|---|
| 43 | 39 | #define BUS_INACTIVE_LIMIT_TIME 0xa8 |
|---|
| 44 | 40 | #define REJECT_TO_OPEN_LIMIT_TIME 0xac |
|---|
| 41 | +#define CQ_INT_CONVERGE_EN 0xb0 |
|---|
| 45 | 42 | #define CFG_AGING_TIME 0xbc |
|---|
| 46 | 43 | #define HGC_DFX_CFG2 0xc0 |
|---|
| 47 | 44 | #define CFG_ABT_SET_QUERY_IPTT 0xd4 |
|---|
| .. | .. |
|---|
| 51 | 48 | #define CFG_ABT_SET_IPTT_DONE 0xd8 |
|---|
| 52 | 49 | #define CFG_ABT_SET_IPTT_DONE_OFF 0 |
|---|
| 53 | 50 | #define HGC_IOMB_PROC1_STATUS 0x104 |
|---|
| 51 | +#define HGC_LM_DFX_STATUS2 0x128 |
|---|
| 52 | +#define HGC_LM_DFX_STATUS2_IOSTLIST_OFF 0 |
|---|
| 53 | +#define HGC_LM_DFX_STATUS2_IOSTLIST_MSK (0xfff << \ |
|---|
| 54 | + HGC_LM_DFX_STATUS2_IOSTLIST_OFF) |
|---|
| 55 | +#define HGC_LM_DFX_STATUS2_ITCTLIST_OFF 12 |
|---|
| 56 | +#define HGC_LM_DFX_STATUS2_ITCTLIST_MSK (0x7ff << \ |
|---|
| 57 | + HGC_LM_DFX_STATUS2_ITCTLIST_OFF) |
|---|
| 58 | +#define HGC_CQE_ECC_ADDR 0x13c |
|---|
| 59 | +#define HGC_CQE_ECC_1B_ADDR_OFF 0 |
|---|
| 60 | +#define HGC_CQE_ECC_1B_ADDR_MSK (0x3f << HGC_CQE_ECC_1B_ADDR_OFF) |
|---|
| 61 | +#define HGC_CQE_ECC_MB_ADDR_OFF 8 |
|---|
| 62 | +#define HGC_CQE_ECC_MB_ADDR_MSK (0x3f << HGC_CQE_ECC_MB_ADDR_OFF) |
|---|
| 63 | +#define HGC_IOST_ECC_ADDR 0x140 |
|---|
| 64 | +#define HGC_IOST_ECC_1B_ADDR_OFF 0 |
|---|
| 65 | +#define HGC_IOST_ECC_1B_ADDR_MSK (0x3ff << HGC_IOST_ECC_1B_ADDR_OFF) |
|---|
| 66 | +#define HGC_IOST_ECC_MB_ADDR_OFF 16 |
|---|
| 67 | +#define HGC_IOST_ECC_MB_ADDR_MSK (0x3ff << HGC_IOST_ECC_MB_ADDR_OFF) |
|---|
| 68 | +#define HGC_DQE_ECC_ADDR 0x144 |
|---|
| 69 | +#define HGC_DQE_ECC_1B_ADDR_OFF 0 |
|---|
| 70 | +#define HGC_DQE_ECC_1B_ADDR_MSK (0xfff << HGC_DQE_ECC_1B_ADDR_OFF) |
|---|
| 71 | +#define HGC_DQE_ECC_MB_ADDR_OFF 16 |
|---|
| 72 | +#define HGC_DQE_ECC_MB_ADDR_MSK (0xfff << HGC_DQE_ECC_MB_ADDR_OFF) |
|---|
| 54 | 73 | #define CHNL_INT_STATUS 0x148 |
|---|
| 74 | +#define TAB_DFX 0x14c |
|---|
| 75 | +#define HGC_ITCT_ECC_ADDR 0x150 |
|---|
| 76 | +#define HGC_ITCT_ECC_1B_ADDR_OFF 0 |
|---|
| 77 | +#define HGC_ITCT_ECC_1B_ADDR_MSK (0x3ff << \ |
|---|
| 78 | + HGC_ITCT_ECC_1B_ADDR_OFF) |
|---|
| 79 | +#define HGC_ITCT_ECC_MB_ADDR_OFF 16 |
|---|
| 80 | +#define HGC_ITCT_ECC_MB_ADDR_MSK (0x3ff << \ |
|---|
| 81 | + HGC_ITCT_ECC_MB_ADDR_OFF) |
|---|
| 55 | 82 | #define HGC_AXI_FIFO_ERR_INFO 0x154 |
|---|
| 56 | 83 | #define AXI_ERR_INFO_OFF 0 |
|---|
| 57 | 84 | #define AXI_ERR_INFO_MSK (0xff << AXI_ERR_INFO_OFF) |
|---|
| 58 | 85 | #define FIFO_ERR_INFO_OFF 8 |
|---|
| 59 | 86 | #define FIFO_ERR_INFO_MSK (0xff << FIFO_ERR_INFO_OFF) |
|---|
| 87 | +#define TAB_RD_TYPE 0x15c |
|---|
| 60 | 88 | #define INT_COAL_EN 0x19c |
|---|
| 61 | 89 | #define OQ_INT_COAL_TIME 0x1a0 |
|---|
| 62 | 90 | #define OQ_INT_COAL_CNT 0x1a4 |
|---|
| .. | .. |
|---|
| 80 | 108 | #define ENT_INT_SRC3_ITC_INT_OFF 15 |
|---|
| 81 | 109 | #define ENT_INT_SRC3_ITC_INT_MSK (0x1 << ENT_INT_SRC3_ITC_INT_OFF) |
|---|
| 82 | 110 | #define ENT_INT_SRC3_ABT_OFF 16 |
|---|
| 111 | +#define ENT_INT_SRC3_DQE_POISON_OFF 18 |
|---|
| 112 | +#define ENT_INT_SRC3_IOST_POISON_OFF 19 |
|---|
| 113 | +#define ENT_INT_SRC3_ITCT_POISON_OFF 20 |
|---|
| 114 | +#define ENT_INT_SRC3_ITCT_NCQ_POISON_OFF 21 |
|---|
| 83 | 115 | #define ENT_INT_SRC_MSK1 0x1c4 |
|---|
| 84 | 116 | #define ENT_INT_SRC_MSK2 0x1c8 |
|---|
| 85 | 117 | #define ENT_INT_SRC_MSK3 0x1cc |
|---|
| .. | .. |
|---|
| 89 | 121 | #define HGC_COM_INT_MSK 0x1d8 |
|---|
| 90 | 122 | #define ENT_INT_SRC_MSK3_ENT95_MSK_MSK (0x1 << ENT_INT_SRC_MSK3_ENT95_MSK_OFF) |
|---|
| 91 | 123 | #define SAS_ECC_INTR 0x1e8 |
|---|
| 124 | +#define SAS_ECC_INTR_DQE_ECC_1B_OFF 0 |
|---|
| 125 | +#define SAS_ECC_INTR_DQE_ECC_MB_OFF 1 |
|---|
| 126 | +#define SAS_ECC_INTR_IOST_ECC_1B_OFF 2 |
|---|
| 127 | +#define SAS_ECC_INTR_IOST_ECC_MB_OFF 3 |
|---|
| 128 | +#define SAS_ECC_INTR_ITCT_ECC_1B_OFF 4 |
|---|
| 129 | +#define SAS_ECC_INTR_ITCT_ECC_MB_OFF 5 |
|---|
| 130 | +#define SAS_ECC_INTR_ITCTLIST_ECC_1B_OFF 6 |
|---|
| 131 | +#define SAS_ECC_INTR_ITCTLIST_ECC_MB_OFF 7 |
|---|
| 132 | +#define SAS_ECC_INTR_IOSTLIST_ECC_1B_OFF 8 |
|---|
| 133 | +#define SAS_ECC_INTR_IOSTLIST_ECC_MB_OFF 9 |
|---|
| 134 | +#define SAS_ECC_INTR_CQE_ECC_1B_OFF 10 |
|---|
| 135 | +#define SAS_ECC_INTR_CQE_ECC_MB_OFF 11 |
|---|
| 136 | +#define SAS_ECC_INTR_NCQ_MEM0_ECC_1B_OFF 12 |
|---|
| 137 | +#define SAS_ECC_INTR_NCQ_MEM0_ECC_MB_OFF 13 |
|---|
| 138 | +#define SAS_ECC_INTR_NCQ_MEM1_ECC_1B_OFF 14 |
|---|
| 139 | +#define SAS_ECC_INTR_NCQ_MEM1_ECC_MB_OFF 15 |
|---|
| 140 | +#define SAS_ECC_INTR_NCQ_MEM2_ECC_1B_OFF 16 |
|---|
| 141 | +#define SAS_ECC_INTR_NCQ_MEM2_ECC_MB_OFF 17 |
|---|
| 142 | +#define SAS_ECC_INTR_NCQ_MEM3_ECC_1B_OFF 18 |
|---|
| 143 | +#define SAS_ECC_INTR_NCQ_MEM3_ECC_MB_OFF 19 |
|---|
| 144 | +#define SAS_ECC_INTR_OOO_RAM_ECC_1B_OFF 20 |
|---|
| 145 | +#define SAS_ECC_INTR_OOO_RAM_ECC_MB_OFF 21 |
|---|
| 92 | 146 | #define SAS_ECC_INTR_MSK 0x1ec |
|---|
| 93 | 147 | #define HGC_ERR_STAT_EN 0x238 |
|---|
| 94 | 148 | #define CQE_SEND_CNT 0x248 |
|---|
| .. | .. |
|---|
| 104 | 158 | #define COMPL_Q_0_DEPTH 0x4e8 |
|---|
| 105 | 159 | #define COMPL_Q_0_WR_PTR 0x4ec |
|---|
| 106 | 160 | #define COMPL_Q_0_RD_PTR 0x4f0 |
|---|
| 161 | +#define HGC_RXM_DFX_STATUS14 0xae8 |
|---|
| 162 | +#define HGC_RXM_DFX_STATUS14_MEM0_OFF 0 |
|---|
| 163 | +#define HGC_RXM_DFX_STATUS14_MEM0_MSK (0x1ff << \ |
|---|
| 164 | + HGC_RXM_DFX_STATUS14_MEM0_OFF) |
|---|
| 165 | +#define HGC_RXM_DFX_STATUS14_MEM1_OFF 9 |
|---|
| 166 | +#define HGC_RXM_DFX_STATUS14_MEM1_MSK (0x1ff << \ |
|---|
| 167 | + HGC_RXM_DFX_STATUS14_MEM1_OFF) |
|---|
| 168 | +#define HGC_RXM_DFX_STATUS14_MEM2_OFF 18 |
|---|
| 169 | +#define HGC_RXM_DFX_STATUS14_MEM2_MSK (0x1ff << \ |
|---|
| 170 | + HGC_RXM_DFX_STATUS14_MEM2_OFF) |
|---|
| 171 | +#define HGC_RXM_DFX_STATUS15 0xaec |
|---|
| 172 | +#define HGC_RXM_DFX_STATUS15_MEM3_OFF 0 |
|---|
| 173 | +#define HGC_RXM_DFX_STATUS15_MEM3_MSK (0x1ff << \ |
|---|
| 174 | + HGC_RXM_DFX_STATUS15_MEM3_OFF) |
|---|
| 107 | 175 | #define AWQOS_AWCACHE_CFG 0xc84 |
|---|
| 108 | 176 | #define ARQOS_ARCACHE_CFG 0xc88 |
|---|
| 109 | 177 | #define HILINK_ERR_DFX 0xe04 |
|---|
| .. | .. |
|---|
| 123 | 191 | #define PHY_CFG_PHY_RST_OFF 3 |
|---|
| 124 | 192 | #define PHY_CFG_PHY_RST_MSK (0x1 << PHY_CFG_PHY_RST_OFF) |
|---|
| 125 | 193 | #define PROG_PHY_LINK_RATE (PORT_BASE + 0x8) |
|---|
| 194 | +#define CFG_PROG_PHY_LINK_RATE_OFF 0 |
|---|
| 195 | +#define CFG_PROG_PHY_LINK_RATE_MSK (0xff << CFG_PROG_PHY_LINK_RATE_OFF) |
|---|
| 196 | +#define CFG_PROG_OOB_PHY_LINK_RATE_OFF 8 |
|---|
| 197 | +#define CFG_PROG_OOB_PHY_LINK_RATE_MSK (0xf << CFG_PROG_OOB_PHY_LINK_RATE_OFF) |
|---|
| 126 | 198 | #define PHY_CTRL (PORT_BASE + 0x14) |
|---|
| 127 | 199 | #define PHY_CTRL_RESET_OFF 0 |
|---|
| 128 | 200 | #define PHY_CTRL_RESET_MSK (0x1 << PHY_CTRL_RESET_OFF) |
|---|
| 201 | +#define CMD_HDR_PIR_OFF 8 |
|---|
| 202 | +#define CMD_HDR_PIR_MSK (0x1 << CMD_HDR_PIR_OFF) |
|---|
| 203 | +#define SERDES_CFG (PORT_BASE + 0x1c) |
|---|
| 204 | +#define CFG_ALOS_CHK_DISABLE_OFF 9 |
|---|
| 205 | +#define CFG_ALOS_CHK_DISABLE_MSK (0x1 << CFG_ALOS_CHK_DISABLE_OFF) |
|---|
| 206 | +#define SAS_PHY_BIST_CTRL (PORT_BASE + 0x2c) |
|---|
| 207 | +#define CFG_BIST_MODE_SEL_OFF 0 |
|---|
| 208 | +#define CFG_BIST_MODE_SEL_MSK (0xf << CFG_BIST_MODE_SEL_OFF) |
|---|
| 209 | +#define CFG_LOOP_TEST_MODE_OFF 14 |
|---|
| 210 | +#define CFG_LOOP_TEST_MODE_MSK (0x3 << CFG_LOOP_TEST_MODE_OFF) |
|---|
| 211 | +#define CFG_RX_BIST_EN_OFF 16 |
|---|
| 212 | +#define CFG_RX_BIST_EN_MSK (0x1 << CFG_RX_BIST_EN_OFF) |
|---|
| 213 | +#define CFG_TX_BIST_EN_OFF 17 |
|---|
| 214 | +#define CFG_TX_BIST_EN_MSK (0x1 << CFG_TX_BIST_EN_OFF) |
|---|
| 215 | +#define CFG_BIST_TEST_OFF 18 |
|---|
| 216 | +#define CFG_BIST_TEST_MSK (0x1 << CFG_BIST_TEST_OFF) |
|---|
| 217 | +#define SAS_PHY_BIST_CODE (PORT_BASE + 0x30) |
|---|
| 218 | +#define SAS_PHY_BIST_CODE1 (PORT_BASE + 0x34) |
|---|
| 219 | +#define SAS_BIST_ERR_CNT (PORT_BASE + 0x38) |
|---|
| 129 | 220 | #define SL_CFG (PORT_BASE + 0x84) |
|---|
| 221 | +#define AIP_LIMIT (PORT_BASE + 0x90) |
|---|
| 130 | 222 | #define SL_CONTROL (PORT_BASE + 0x94) |
|---|
| 131 | 223 | #define SL_CONTROL_NOTIFY_EN_OFF 0 |
|---|
| 132 | 224 | #define SL_CONTROL_NOTIFY_EN_MSK (0x1 << SL_CONTROL_NOTIFY_EN_OFF) |
|---|
| .. | .. |
|---|
| 167 | 259 | #define CHL_INT0_PHY_RDY_OFF 5 |
|---|
| 168 | 260 | #define CHL_INT0_PHY_RDY_MSK (0x1 << CHL_INT0_PHY_RDY_OFF) |
|---|
| 169 | 261 | #define CHL_INT1 (PORT_BASE + 0x1b8) |
|---|
| 170 | | -#define CHL_INT1_DMAC_TX_ECC_ERR_OFF 15 |
|---|
| 171 | | -#define CHL_INT1_DMAC_TX_ECC_ERR_MSK (0x1 << CHL_INT1_DMAC_TX_ECC_ERR_OFF) |
|---|
| 172 | | -#define CHL_INT1_DMAC_RX_ECC_ERR_OFF 17 |
|---|
| 173 | | -#define CHL_INT1_DMAC_RX_ECC_ERR_MSK (0x1 << CHL_INT1_DMAC_RX_ECC_ERR_OFF) |
|---|
| 262 | +#define CHL_INT1_DMAC_TX_ECC_MB_ERR_OFF 15 |
|---|
| 263 | +#define CHL_INT1_DMAC_TX_ECC_1B_ERR_OFF 16 |
|---|
| 264 | +#define CHL_INT1_DMAC_RX_ECC_MB_ERR_OFF 17 |
|---|
| 265 | +#define CHL_INT1_DMAC_RX_ECC_1B_ERR_OFF 18 |
|---|
| 174 | 266 | #define CHL_INT1_DMAC_TX_AXI_WR_ERR_OFF 19 |
|---|
| 175 | 267 | #define CHL_INT1_DMAC_TX_AXI_RD_ERR_OFF 20 |
|---|
| 176 | 268 | #define CHL_INT1_DMAC_RX_AXI_WR_ERR_OFF 21 |
|---|
| 177 | 269 | #define CHL_INT1_DMAC_RX_AXI_RD_ERR_OFF 22 |
|---|
| 270 | +#define CHL_INT1_DMAC_TX_FIFO_ERR_OFF 23 |
|---|
| 271 | +#define CHL_INT1_DMAC_RX_FIFO_ERR_OFF 24 |
|---|
| 272 | +#define CHL_INT1_DMAC_TX_AXI_RUSER_ERR_OFF 26 |
|---|
| 273 | +#define CHL_INT1_DMAC_RX_AXI_RUSER_ERR_OFF 27 |
|---|
| 178 | 274 | #define CHL_INT2 (PORT_BASE + 0x1bc) |
|---|
| 179 | 275 | #define CHL_INT2_SL_IDAF_TOUT_CONF_OFF 0 |
|---|
| 276 | +#define CHL_INT2_RX_DISP_ERR_OFF 28 |
|---|
| 277 | +#define CHL_INT2_RX_CODE_ERR_OFF 29 |
|---|
| 180 | 278 | #define CHL_INT2_RX_INVLD_DW_OFF 30 |
|---|
| 181 | 279 | #define CHL_INT2_STP_LINK_TIMEOUT_OFF 31 |
|---|
| 182 | 280 | #define CHL_INT0_MSK (PORT_BASE + 0x1c0) |
|---|
| 183 | 281 | #define CHL_INT1_MSK (PORT_BASE + 0x1c4) |
|---|
| 184 | 282 | #define CHL_INT2_MSK (PORT_BASE + 0x1c8) |
|---|
| 283 | +#define SAS_EC_INT_COAL_TIME (PORT_BASE + 0x1cc) |
|---|
| 185 | 284 | #define CHL_INT_COAL_EN (PORT_BASE + 0x1d0) |
|---|
| 186 | 285 | #define SAS_RX_TRAIN_TIMER (PORT_BASE + 0x2a4) |
|---|
| 187 | 286 | #define PHY_CTRL_RDY_MSK (PORT_BASE + 0x2b0) |
|---|
| .. | .. |
|---|
| 198 | 297 | #define DMA_RX_STATUS_BUSY_MSK (0x1 << DMA_RX_STATUS_BUSY_OFF) |
|---|
| 199 | 298 | |
|---|
| 200 | 299 | #define COARSETUNE_TIME (PORT_BASE + 0x304) |
|---|
| 300 | +#define TXDEEMPH_G1 (PORT_BASE + 0x350) |
|---|
| 201 | 301 | #define ERR_CNT_DWS_LOST (PORT_BASE + 0x380) |
|---|
| 202 | 302 | #define ERR_CNT_RESET_PROB (PORT_BASE + 0x384) |
|---|
| 203 | 303 | #define ERR_CNT_INVLD_DW (PORT_BASE + 0x390) |
|---|
| 304 | +#define ERR_CNT_CODE_ERR (PORT_BASE + 0x394) |
|---|
| 204 | 305 | #define ERR_CNT_DISP_ERR (PORT_BASE + 0x398) |
|---|
| 205 | 306 | |
|---|
| 206 | 307 | #define DEFAULT_ITCT_HW 2048 /* reset value, not reprogrammed */ |
|---|
| .. | .. |
|---|
| 218 | 319 | #define AM_CFG_SINGLE_PORT_MAX_TRANS (0x5014) |
|---|
| 219 | 320 | #define AXI_CFG (0x5100) |
|---|
| 220 | 321 | #define AM_ROB_ECC_ERR_ADDR (0x510c) |
|---|
| 221 | | -#define AM_ROB_ECC_ONEBIT_ERR_ADDR_OFF 0 |
|---|
| 222 | | -#define AM_ROB_ECC_ONEBIT_ERR_ADDR_MSK (0xff << AM_ROB_ECC_ONEBIT_ERR_ADDR_OFF) |
|---|
| 223 | | -#define AM_ROB_ECC_MULBIT_ERR_ADDR_OFF 8 |
|---|
| 224 | | -#define AM_ROB_ECC_MULBIT_ERR_ADDR_MSK (0xff << AM_ROB_ECC_MULBIT_ERR_ADDR_OFF) |
|---|
| 322 | +#define AM_ROB_ECC_ERR_ADDR_OFF 0 |
|---|
| 323 | +#define AM_ROB_ECC_ERR_ADDR_MSK 0xffffffff |
|---|
| 225 | 324 | |
|---|
| 226 | 325 | /* RAS registers need init */ |
|---|
| 227 | 326 | #define RAS_BASE (0x6000) |
|---|
| .. | .. |
|---|
| 331 | 430 | #define ITCT_HDR_RTOLT_OFF 48 |
|---|
| 332 | 431 | #define ITCT_HDR_RTOLT_MSK (0xffffULL << ITCT_HDR_RTOLT_OFF) |
|---|
| 333 | 432 | |
|---|
| 433 | +struct hisi_sas_protect_iu_v3_hw { |
|---|
| 434 | + u32 dw0; |
|---|
| 435 | + u32 lbrtcv; |
|---|
| 436 | + u32 lbrtgv; |
|---|
| 437 | + u32 dw3; |
|---|
| 438 | + u32 dw4; |
|---|
| 439 | + u32 dw5; |
|---|
| 440 | + u32 rsv; |
|---|
| 441 | +}; |
|---|
| 442 | + |
|---|
| 334 | 443 | struct hisi_sas_complete_v3_hdr { |
|---|
| 335 | 444 | __le32 dw0; |
|---|
| 336 | 445 | __le32 dw1; |
|---|
| .. | .. |
|---|
| 370 | 479 | ((fis.command == ATA_CMD_DEV_RESET) && \ |
|---|
| 371 | 480 | ((fis.control & ATA_SRST) != 0))) |
|---|
| 372 | 481 | |
|---|
| 482 | +#define T10_INSRT_EN_OFF 0 |
|---|
| 483 | +#define T10_INSRT_EN_MSK (1 << T10_INSRT_EN_OFF) |
|---|
| 484 | +#define T10_RMV_EN_OFF 1 |
|---|
| 485 | +#define T10_RMV_EN_MSK (1 << T10_RMV_EN_OFF) |
|---|
| 486 | +#define T10_RPLC_EN_OFF 2 |
|---|
| 487 | +#define T10_RPLC_EN_MSK (1 << T10_RPLC_EN_OFF) |
|---|
| 488 | +#define T10_CHK_EN_OFF 3 |
|---|
| 489 | +#define T10_CHK_EN_MSK (1 << T10_CHK_EN_OFF) |
|---|
| 490 | +#define INCR_LBRT_OFF 5 |
|---|
| 491 | +#define INCR_LBRT_MSK (1 << INCR_LBRT_OFF) |
|---|
| 492 | +#define USR_DATA_BLOCK_SZ_OFF 20 |
|---|
| 493 | +#define USR_DATA_BLOCK_SZ_MSK (0x3 << USR_DATA_BLOCK_SZ_OFF) |
|---|
| 494 | +#define T10_CHK_MSK_OFF 16 |
|---|
| 495 | +#define T10_CHK_REF_TAG_MSK (0xf0 << T10_CHK_MSK_OFF) |
|---|
| 496 | +#define T10_CHK_APP_TAG_MSK (0xc << T10_CHK_MSK_OFF) |
|---|
| 497 | + |
|---|
| 498 | +#define BASE_VECTORS_V3_HW 16 |
|---|
| 499 | +#define MIN_AFFINE_VECTORS_V3_HW (BASE_VECTORS_V3_HW + 1) |
|---|
| 500 | + |
|---|
| 501 | +#define CHNL_INT_STS_MSK 0xeeeeeeee |
|---|
| 502 | +#define CHNL_INT_STS_PHY_MSK 0xe |
|---|
| 503 | +#define CHNL_INT_STS_INT0_MSK BIT(1) |
|---|
| 504 | +#define CHNL_INT_STS_INT1_MSK BIT(2) |
|---|
| 505 | +#define CHNL_INT_STS_INT2_MSK BIT(3) |
|---|
| 506 | +#define CHNL_WIDTH 4 |
|---|
| 507 | + |
|---|
| 508 | +enum { |
|---|
| 509 | + DSM_FUNC_ERR_HANDLE_MSI = 0, |
|---|
| 510 | +}; |
|---|
| 511 | + |
|---|
| 512 | +static bool hisi_sas_intr_conv; |
|---|
| 513 | +MODULE_PARM_DESC(intr_conv, "interrupt converge enable (0-1)"); |
|---|
| 514 | + |
|---|
| 515 | +/* permit overriding the host protection capabilities mask (EEDP/T10 PI) */ |
|---|
| 516 | +static int prot_mask; |
|---|
| 517 | +module_param(prot_mask, int, 0444); |
|---|
| 518 | +MODULE_PARM_DESC(prot_mask, " host protection capabilities mask, def=0x0 "); |
|---|
| 519 | + |
|---|
| 520 | +static bool auto_affine_msi_experimental; |
|---|
| 521 | +module_param(auto_affine_msi_experimental, bool, 0444); |
|---|
| 522 | +MODULE_PARM_DESC(auto_affine_msi_experimental, "Enable auto-affinity of MSI IRQs as experimental:\n" |
|---|
| 523 | + "default is off"); |
|---|
| 524 | + |
|---|
| 373 | 525 | static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off) |
|---|
| 374 | 526 | { |
|---|
| 375 | 527 | void __iomem *regs = hisi_hba->regs + off; |
|---|
| 376 | 528 | |
|---|
| 377 | 529 | return readl(regs); |
|---|
| 378 | | -} |
|---|
| 379 | | - |
|---|
| 380 | | -static u32 hisi_sas_read32_relaxed(struct hisi_hba *hisi_hba, u32 off) |
|---|
| 381 | | -{ |
|---|
| 382 | | - void __iomem *regs = hisi_hba->regs + off; |
|---|
| 383 | | - |
|---|
| 384 | | - return readl_relaxed(regs); |
|---|
| 385 | 530 | } |
|---|
| 386 | 531 | |
|---|
| 387 | 532 | static void hisi_sas_write32(struct hisi_hba *hisi_hba, u32 off, u32 val) |
|---|
| .. | .. |
|---|
| 423 | 568 | |
|---|
| 424 | 569 | static void init_reg_v3_hw(struct hisi_hba *hisi_hba) |
|---|
| 425 | 570 | { |
|---|
| 426 | | - struct pci_dev *pdev = hisi_hba->pci_dev; |
|---|
| 427 | | - int i; |
|---|
| 571 | + int i, j; |
|---|
| 428 | 572 | |
|---|
| 429 | 573 | /* Global registers init */ |
|---|
| 430 | 574 | hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, |
|---|
| 431 | 575 | (u32)((1ULL << hisi_hba->queue_count) - 1)); |
|---|
| 576 | + hisi_sas_write32(hisi_hba, SAS_AXI_USER3, 0); |
|---|
| 432 | 577 | hisi_sas_write32(hisi_hba, CFG_MAX_TAG, 0xfff0400); |
|---|
| 433 | 578 | hisi_sas_write32(hisi_hba, HGC_SAS_TXFAIL_RETRY_CTRL, 0x108); |
|---|
| 579 | + hisi_sas_write32(hisi_hba, CFG_AGING_TIME, 0x1); |
|---|
| 434 | 580 | hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x1); |
|---|
| 435 | 581 | hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, 0x1); |
|---|
| 436 | 582 | hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, 0x1); |
|---|
| 583 | + hisi_sas_write32(hisi_hba, CQ_INT_CONVERGE_EN, |
|---|
| 584 | + hisi_sas_intr_conv); |
|---|
| 437 | 585 | hisi_sas_write32(hisi_hba, OQ_INT_SRC, 0xffff); |
|---|
| 438 | 586 | hisi_sas_write32(hisi_hba, ENT_INT_SRC1, 0xffffffff); |
|---|
| 439 | 587 | hisi_sas_write32(hisi_hba, ENT_INT_SRC2, 0xffffffff); |
|---|
| 440 | 588 | hisi_sas_write32(hisi_hba, ENT_INT_SRC3, 0xffffffff); |
|---|
| 441 | 589 | hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, 0xfefefefe); |
|---|
| 442 | 590 | hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK2, 0xfefefefe); |
|---|
| 443 | | - if (pdev->revision >= 0x21) |
|---|
| 444 | | - hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xffff7fff); |
|---|
| 445 | | - else |
|---|
| 446 | | - hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xfffe20ff); |
|---|
| 591 | + hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xffc220ff); |
|---|
| 447 | 592 | hisi_sas_write32(hisi_hba, CHNL_PHYUPDOWN_INT_MSK, 0x0); |
|---|
| 448 | 593 | hisi_sas_write32(hisi_hba, CHNL_ENT_INT_MSK, 0x0); |
|---|
| 449 | 594 | hisi_sas_write32(hisi_hba, HGC_COM_INT_MSK, 0x0); |
|---|
| 450 | | - hisi_sas_write32(hisi_hba, SAS_ECC_INTR_MSK, 0x0); |
|---|
| 595 | + hisi_sas_write32(hisi_hba, SAS_ECC_INTR_MSK, 0x155555); |
|---|
| 451 | 596 | hisi_sas_write32(hisi_hba, AWQOS_AWCACHE_CFG, 0xf0f0); |
|---|
| 452 | 597 | hisi_sas_write32(hisi_hba, ARQOS_ARCACHE_CFG, 0xf0f0); |
|---|
| 453 | 598 | for (i = 0; i < hisi_hba->queue_count; i++) |
|---|
| 454 | | - hisi_sas_write32(hisi_hba, OQ0_INT_SRC_MSK+0x4*i, 0); |
|---|
| 599 | + hisi_sas_write32(hisi_hba, OQ0_INT_SRC_MSK + 0x4 * i, 0); |
|---|
| 455 | 600 | |
|---|
| 456 | 601 | hisi_sas_write32(hisi_hba, HYPER_STREAM_ID_EN_CFG, 1); |
|---|
| 457 | 602 | |
|---|
| 458 | 603 | for (i = 0; i < hisi_hba->n_phy; i++) { |
|---|
| 604 | + enum sas_linkrate max; |
|---|
| 459 | 605 | struct hisi_sas_phy *phy = &hisi_hba->phy[i]; |
|---|
| 460 | 606 | struct asd_sas_phy *sas_phy = &phy->sas_phy; |
|---|
| 461 | | - u32 prog_phy_link_rate = 0x800; |
|---|
| 607 | + u32 prog_phy_link_rate = hisi_sas_phy_read32(hisi_hba, i, |
|---|
| 608 | + PROG_PHY_LINK_RATE); |
|---|
| 462 | 609 | |
|---|
| 610 | + prog_phy_link_rate &= ~CFG_PROG_PHY_LINK_RATE_MSK; |
|---|
| 463 | 611 | if (!sas_phy->phy || (sas_phy->phy->maximum_linkrate < |
|---|
| 464 | | - SAS_LINK_RATE_1_5_GBPS)) { |
|---|
| 465 | | - prog_phy_link_rate = 0x855; |
|---|
| 466 | | - } else { |
|---|
| 467 | | - enum sas_linkrate max = sas_phy->phy->maximum_linkrate; |
|---|
| 468 | | - |
|---|
| 469 | | - prog_phy_link_rate = |
|---|
| 470 | | - hisi_sas_get_prog_phy_linkrate_mask(max) | |
|---|
| 471 | | - 0x800; |
|---|
| 472 | | - } |
|---|
| 612 | + SAS_LINK_RATE_1_5_GBPS)) |
|---|
| 613 | + max = SAS_LINK_RATE_12_0_GBPS; |
|---|
| 614 | + else |
|---|
| 615 | + max = sas_phy->phy->maximum_linkrate; |
|---|
| 616 | + prog_phy_link_rate |= hisi_sas_get_prog_phy_linkrate_mask(max); |
|---|
| 473 | 617 | hisi_sas_phy_write32(hisi_hba, i, PROG_PHY_LINK_RATE, |
|---|
| 474 | 618 | prog_phy_link_rate); |
|---|
| 619 | + hisi_sas_phy_write32(hisi_hba, i, SERDES_CFG, 0xffc00); |
|---|
| 475 | 620 | hisi_sas_phy_write32(hisi_hba, i, SAS_RX_TRAIN_TIMER, 0x13e80); |
|---|
| 476 | 621 | hisi_sas_phy_write32(hisi_hba, i, CHL_INT0, 0xffffffff); |
|---|
| 477 | 622 | hisi_sas_phy_write32(hisi_hba, i, CHL_INT1, 0xffffffff); |
|---|
| 478 | 623 | hisi_sas_phy_write32(hisi_hba, i, CHL_INT2, 0xffffffff); |
|---|
| 479 | 624 | hisi_sas_phy_write32(hisi_hba, i, RXOP_CHECK_CFG_H, 0x1000); |
|---|
| 480 | | - if (pdev->revision >= 0x21) |
|---|
| 481 | | - hisi_sas_phy_write32(hisi_hba, i, CHL_INT1_MSK, |
|---|
| 482 | | - 0xffffffff); |
|---|
| 483 | | - else |
|---|
| 484 | | - hisi_sas_phy_write32(hisi_hba, i, CHL_INT1_MSK, |
|---|
| 485 | | - 0xff87ffff); |
|---|
| 625 | + hisi_sas_phy_write32(hisi_hba, i, CHL_INT1_MSK, 0xf2057fff); |
|---|
| 486 | 626 | hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0xffffbfe); |
|---|
| 487 | 627 | hisi_sas_phy_write32(hisi_hba, i, PHY_CTRL_RDY_MSK, 0x0); |
|---|
| 488 | 628 | hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_NOT_RDY_MSK, 0x0); |
|---|
| .. | .. |
|---|
| 493 | 633 | hisi_sas_phy_write32(hisi_hba, i, STP_LINK_TIMER, 0x7f7a120); |
|---|
| 494 | 634 | hisi_sas_phy_write32(hisi_hba, i, CON_CFG_DRIVER, 0x2a0a01); |
|---|
| 495 | 635 | hisi_sas_phy_write32(hisi_hba, i, SAS_SSP_CON_TIMER_CFG, 0x32); |
|---|
| 636 | + hisi_sas_phy_write32(hisi_hba, i, SAS_EC_INT_COAL_TIME, |
|---|
| 637 | + 0x30f4240); |
|---|
| 496 | 638 | /* used for 12G negotiate */ |
|---|
| 497 | 639 | hisi_sas_phy_write32(hisi_hba, i, COARSETUNE_TIME, 0x1e); |
|---|
| 640 | + hisi_sas_phy_write32(hisi_hba, i, AIP_LIMIT, 0x2ffff); |
|---|
| 641 | + |
|---|
| 642 | + /* get default FFE configuration for BIST */ |
|---|
| 643 | + for (j = 0; j < FFE_CFG_MAX; j++) { |
|---|
| 644 | + u32 val = hisi_sas_phy_read32(hisi_hba, i, |
|---|
| 645 | + TXDEEMPH_G1 + (j * 0x4)); |
|---|
| 646 | + hisi_hba->debugfs_bist_ffe[i][j] = val; |
|---|
| 647 | + } |
|---|
| 498 | 648 | } |
|---|
| 499 | 649 | |
|---|
| 500 | 650 | for (i = 0; i < hisi_hba->queue_count; i++) { |
|---|
| .. | .. |
|---|
| 619 | 769 | struct domain_device *parent_dev = device->parent; |
|---|
| 620 | 770 | struct asd_sas_port *sas_port = device->port; |
|---|
| 621 | 771 | struct hisi_sas_port *port = to_hisi_sas_port(sas_port); |
|---|
| 772 | + u64 sas_addr; |
|---|
| 622 | 773 | |
|---|
| 623 | 774 | memset(itct, 0, sizeof(*itct)); |
|---|
| 624 | 775 | |
|---|
| .. | .. |
|---|
| 632 | 783 | break; |
|---|
| 633 | 784 | case SAS_SATA_DEV: |
|---|
| 634 | 785 | case SAS_SATA_PENDING: |
|---|
| 635 | | - if (parent_dev && DEV_IS_EXPANDER(parent_dev->dev_type)) |
|---|
| 786 | + if (parent_dev && dev_is_expander(parent_dev->dev_type)) |
|---|
| 636 | 787 | qw0 = HISI_SAS_DEV_TYPE_STP << ITCT_HDR_DEV_TYPE_OFF; |
|---|
| 637 | 788 | else |
|---|
| 638 | 789 | qw0 = HISI_SAS_DEV_TYPE_SATA << ITCT_HDR_DEV_TYPE_OFF; |
|---|
| .. | .. |
|---|
| 651 | 802 | itct->qw0 = cpu_to_le64(qw0); |
|---|
| 652 | 803 | |
|---|
| 653 | 804 | /* qw1 */ |
|---|
| 654 | | - memcpy(&itct->sas_addr, device->sas_addr, SAS_ADDR_SIZE); |
|---|
| 655 | | - itct->sas_addr = __swab64(itct->sas_addr); |
|---|
| 805 | + memcpy(&sas_addr, device->sas_addr, SAS_ADDR_SIZE); |
|---|
| 806 | + itct->sas_addr = cpu_to_le64(__swab64(sas_addr)); |
|---|
| 656 | 807 | |
|---|
| 657 | 808 | /* qw2 */ |
|---|
| 658 | 809 | if (!dev_is_sata(device)) |
|---|
| .. | .. |
|---|
| 660 | 811 | (0x1ULL << ITCT_HDR_RTOLT_OFF)); |
|---|
| 661 | 812 | } |
|---|
| 662 | 813 | |
|---|
| 663 | | -static void clear_itct_v3_hw(struct hisi_hba *hisi_hba, |
|---|
| 664 | | - struct hisi_sas_device *sas_dev) |
|---|
| 814 | +static int clear_itct_v3_hw(struct hisi_hba *hisi_hba, |
|---|
| 815 | + struct hisi_sas_device *sas_dev) |
|---|
| 665 | 816 | { |
|---|
| 666 | 817 | DECLARE_COMPLETION_ONSTACK(completion); |
|---|
| 667 | 818 | u64 dev_id = sas_dev->device_id; |
|---|
| 668 | 819 | struct hisi_sas_itct *itct = &hisi_hba->itct[dev_id]; |
|---|
| 669 | 820 | u32 reg_val = hisi_sas_read32(hisi_hba, ENT_INT_SRC3); |
|---|
| 821 | + struct device *dev = hisi_hba->dev; |
|---|
| 670 | 822 | |
|---|
| 671 | 823 | sas_dev->completion = &completion; |
|---|
| 672 | 824 | |
|---|
| .. | .. |
|---|
| 675 | 827 | hisi_sas_write32(hisi_hba, ENT_INT_SRC3, |
|---|
| 676 | 828 | ENT_INT_SRC3_ITC_INT_MSK); |
|---|
| 677 | 829 | |
|---|
| 678 | | - /* clear the itct table*/ |
|---|
| 830 | + /* clear the itct table */ |
|---|
| 679 | 831 | reg_val = ITCT_CLR_EN_MSK | (dev_id & ITCT_DEV_MSK); |
|---|
| 680 | 832 | hisi_sas_write32(hisi_hba, ITCT_CLR, reg_val); |
|---|
| 681 | 833 | |
|---|
| 682 | | - wait_for_completion(sas_dev->completion); |
|---|
| 834 | + if (!wait_for_completion_timeout(sas_dev->completion, |
|---|
| 835 | + CLEAR_ITCT_TIMEOUT * HZ)) { |
|---|
| 836 | + dev_warn(dev, "failed to clear ITCT\n"); |
|---|
| 837 | + return -ETIMEDOUT; |
|---|
| 838 | + } |
|---|
| 839 | + |
|---|
| 683 | 840 | memset(itct, 0, sizeof(struct hisi_sas_itct)); |
|---|
| 841 | + return 0; |
|---|
| 684 | 842 | } |
|---|
| 685 | 843 | |
|---|
| 686 | 844 | static void dereg_device_v3_hw(struct hisi_hba *hisi_hba, |
|---|
| .. | .. |
|---|
| 745 | 903 | static int hw_init_v3_hw(struct hisi_hba *hisi_hba) |
|---|
| 746 | 904 | { |
|---|
| 747 | 905 | struct device *dev = hisi_hba->dev; |
|---|
| 906 | + struct acpi_device *acpi_dev; |
|---|
| 907 | + union acpi_object *obj; |
|---|
| 908 | + guid_t guid; |
|---|
| 748 | 909 | int rc; |
|---|
| 749 | 910 | |
|---|
| 750 | 911 | rc = reset_hw_v3_hw(hisi_hba); |
|---|
| 751 | 912 | if (rc) { |
|---|
| 752 | | - dev_err(dev, "hisi_sas_reset_hw failed, rc=%d", rc); |
|---|
| 913 | + dev_err(dev, "hisi_sas_reset_hw failed, rc=%d\n", rc); |
|---|
| 753 | 914 | return rc; |
|---|
| 754 | 915 | } |
|---|
| 755 | 916 | |
|---|
| 756 | 917 | msleep(100); |
|---|
| 757 | 918 | init_reg_v3_hw(hisi_hba); |
|---|
| 758 | 919 | |
|---|
| 920 | + if (guid_parse("D5918B4B-37AE-4E10-A99F-E5E8A6EF4C1F", &guid)) { |
|---|
| 921 | + dev_err(dev, "Parse GUID failed\n"); |
|---|
| 922 | + return -EINVAL; |
|---|
| 923 | + } |
|---|
| 924 | + |
|---|
| 925 | + /* |
|---|
| 926 | + * This DSM handles some hardware-related configurations: |
|---|
| 927 | + * 1. Switch over to MSI error handling in kernel |
|---|
| 928 | + * 2. BIOS *may* reset some register values through this method |
|---|
| 929 | + */ |
|---|
| 930 | + obj = acpi_evaluate_dsm(ACPI_HANDLE(dev), &guid, 0, |
|---|
| 931 | + DSM_FUNC_ERR_HANDLE_MSI, NULL); |
|---|
| 932 | + if (!obj) |
|---|
| 933 | + dev_warn(dev, "can not find DSM method, ignore\n"); |
|---|
| 934 | + else |
|---|
| 935 | + ACPI_FREE(obj); |
|---|
| 936 | + |
|---|
| 937 | + acpi_dev = ACPI_COMPANION(dev); |
|---|
| 938 | + if (!acpi_device_power_manageable(acpi_dev)) |
|---|
| 939 | + dev_notice(dev, "neither _PS0 nor _PR0 is defined\n"); |
|---|
| 759 | 940 | return 0; |
|---|
| 760 | 941 | } |
|---|
| 761 | 942 | |
|---|
| .. | .. |
|---|
| 771 | 952 | static void disable_phy_v3_hw(struct hisi_hba *hisi_hba, int phy_no) |
|---|
| 772 | 953 | { |
|---|
| 773 | 954 | u32 cfg = hisi_sas_phy_read32(hisi_hba, phy_no, PHY_CFG); |
|---|
| 955 | + u32 irq_msk = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT2_MSK); |
|---|
| 956 | + static const u32 msk = BIT(CHL_INT2_RX_DISP_ERR_OFF) | |
|---|
| 957 | + BIT(CHL_INT2_RX_CODE_ERR_OFF) | |
|---|
| 958 | + BIT(CHL_INT2_RX_INVLD_DW_OFF); |
|---|
| 774 | 959 | u32 state; |
|---|
| 960 | + |
|---|
| 961 | + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2_MSK, msk | irq_msk); |
|---|
| 775 | 962 | |
|---|
| 776 | 963 | cfg &= ~PHY_CFG_ENA_MSK; |
|---|
| 777 | 964 | hisi_sas_phy_write32(hisi_hba, phy_no, PHY_CFG, cfg); |
|---|
| .. | .. |
|---|
| 783 | 970 | cfg |= PHY_CFG_PHY_RST_MSK; |
|---|
| 784 | 971 | hisi_sas_phy_write32(hisi_hba, phy_no, PHY_CFG, cfg); |
|---|
| 785 | 972 | } |
|---|
| 973 | + |
|---|
| 974 | + udelay(1); |
|---|
| 975 | + |
|---|
| 976 | + hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_INVLD_DW); |
|---|
| 977 | + hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_DISP_ERR); |
|---|
| 978 | + hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_CODE_ERR); |
|---|
| 979 | + |
|---|
| 980 | + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2, msk); |
|---|
| 981 | + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2_MSK, irq_msk); |
|---|
| 786 | 982 | } |
|---|
| 787 | 983 | |
|---|
| 788 | 984 | static void start_phy_v3_hw(struct hisi_hba *hisi_hba, int phy_no) |
|---|
| .. | .. |
|---|
| 797 | 993 | struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; |
|---|
| 798 | 994 | u32 txid_auto; |
|---|
| 799 | 995 | |
|---|
| 800 | | - disable_phy_v3_hw(hisi_hba, phy_no); |
|---|
| 996 | + hisi_sas_phy_enable(hisi_hba, phy_no, 0); |
|---|
| 801 | 997 | if (phy->identify.device_type == SAS_END_DEVICE) { |
|---|
| 802 | 998 | txid_auto = hisi_sas_phy_read32(hisi_hba, phy_no, TXID_AUTO); |
|---|
| 803 | 999 | hisi_sas_phy_write32(hisi_hba, phy_no, TXID_AUTO, |
|---|
| 804 | 1000 | txid_auto | TX_HARDRST_MSK); |
|---|
| 805 | 1001 | } |
|---|
| 806 | 1002 | msleep(100); |
|---|
| 807 | | - start_phy_v3_hw(hisi_hba, phy_no); |
|---|
| 1003 | + hisi_sas_phy_enable(hisi_hba, phy_no, 1); |
|---|
| 808 | 1004 | } |
|---|
| 809 | 1005 | |
|---|
| 810 | 1006 | static enum sas_linkrate phy_get_max_linkrate_v3_hw(void) |
|---|
| .. | .. |
|---|
| 823 | 1019 | if (!sas_phy->phy->enabled) |
|---|
| 824 | 1020 | continue; |
|---|
| 825 | 1021 | |
|---|
| 826 | | - start_phy_v3_hw(hisi_hba, i); |
|---|
| 1022 | + hisi_sas_phy_enable(hisi_hba, i, 1); |
|---|
| 827 | 1023 | } |
|---|
| 828 | 1024 | } |
|---|
| 829 | 1025 | |
|---|
| .. | .. |
|---|
| 852 | 1048 | bitmap |= BIT(i); |
|---|
| 853 | 1049 | |
|---|
| 854 | 1050 | return bitmap; |
|---|
| 855 | | -} |
|---|
| 856 | | - |
|---|
| 857 | | -/** |
|---|
| 858 | | - * The callpath to this function and upto writing the write |
|---|
| 859 | | - * queue pointer should be safe from interruption. |
|---|
| 860 | | - */ |
|---|
| 861 | | -static int |
|---|
| 862 | | -get_free_slot_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_dq *dq) |
|---|
| 863 | | -{ |
|---|
| 864 | | - struct device *dev = hisi_hba->dev; |
|---|
| 865 | | - int queue = dq->id; |
|---|
| 866 | | - u32 r, w; |
|---|
| 867 | | - |
|---|
| 868 | | - w = dq->wr_point; |
|---|
| 869 | | - r = hisi_sas_read32_relaxed(hisi_hba, |
|---|
| 870 | | - DLVRY_Q_0_RD_PTR + (queue * 0x14)); |
|---|
| 871 | | - if (r == (w+1) % HISI_SAS_QUEUE_SLOTS) { |
|---|
| 872 | | - dev_warn(dev, "full queue=%d r=%d w=%d\n", |
|---|
| 873 | | - queue, r, w); |
|---|
| 874 | | - return -EAGAIN; |
|---|
| 875 | | - } |
|---|
| 876 | | - |
|---|
| 877 | | - dq->wr_point = (dq->wr_point + 1) % HISI_SAS_QUEUE_SLOTS; |
|---|
| 878 | | - |
|---|
| 879 | | - return w; |
|---|
| 880 | 1051 | } |
|---|
| 881 | 1052 | |
|---|
| 882 | 1053 | static void start_delivery_v3_hw(struct hisi_sas_dq *dq) |
|---|
| .. | .. |
|---|
| 926 | 1097 | |
|---|
| 927 | 1098 | hdr->prd_table_addr = cpu_to_le64(hisi_sas_sge_addr_dma(slot)); |
|---|
| 928 | 1099 | |
|---|
| 929 | | - hdr->sg_len = cpu_to_le32(n_elem << CMD_HDR_DATA_SGL_LEN_OFF); |
|---|
| 1100 | + hdr->sg_len |= cpu_to_le32(n_elem << CMD_HDR_DATA_SGL_LEN_OFF); |
|---|
| 1101 | +} |
|---|
| 1102 | + |
|---|
| 1103 | +static void prep_prd_sge_dif_v3_hw(struct hisi_hba *hisi_hba, |
|---|
| 1104 | + struct hisi_sas_slot *slot, |
|---|
| 1105 | + struct hisi_sas_cmd_hdr *hdr, |
|---|
| 1106 | + struct scatterlist *scatter, |
|---|
| 1107 | + int n_elem) |
|---|
| 1108 | +{ |
|---|
| 1109 | + struct hisi_sas_sge_dif_page *sge_dif_page; |
|---|
| 1110 | + struct scatterlist *sg; |
|---|
| 1111 | + int i; |
|---|
| 1112 | + |
|---|
| 1113 | + sge_dif_page = hisi_sas_sge_dif_addr_mem(slot); |
|---|
| 1114 | + |
|---|
| 1115 | + for_each_sg(scatter, sg, n_elem, i) { |
|---|
| 1116 | + struct hisi_sas_sge *entry = &sge_dif_page->sge[i]; |
|---|
| 1117 | + |
|---|
| 1118 | + entry->addr = cpu_to_le64(sg_dma_address(sg)); |
|---|
| 1119 | + entry->page_ctrl_0 = 0; |
|---|
| 1120 | + entry->page_ctrl_1 = 0; |
|---|
| 1121 | + entry->data_len = cpu_to_le32(sg_dma_len(sg)); |
|---|
| 1122 | + entry->data_off = 0; |
|---|
| 1123 | + } |
|---|
| 1124 | + |
|---|
| 1125 | + hdr->dif_prd_table_addr = |
|---|
| 1126 | + cpu_to_le64(hisi_sas_sge_dif_addr_dma(slot)); |
|---|
| 1127 | + |
|---|
| 1128 | + hdr->sg_len |= cpu_to_le32(n_elem << CMD_HDR_DIF_SGL_LEN_OFF); |
|---|
| 1129 | +} |
|---|
| 1130 | + |
|---|
| 1131 | +static u32 get_prot_chk_msk_v3_hw(struct scsi_cmnd *scsi_cmnd) |
|---|
| 1132 | +{ |
|---|
| 1133 | + unsigned char prot_flags = scsi_cmnd->prot_flags; |
|---|
| 1134 | + |
|---|
| 1135 | + if (prot_flags & SCSI_PROT_REF_CHECK) |
|---|
| 1136 | + return T10_CHK_APP_TAG_MSK; |
|---|
| 1137 | + return T10_CHK_REF_TAG_MSK | T10_CHK_APP_TAG_MSK; |
|---|
| 1138 | +} |
|---|
| 1139 | + |
|---|
| 1140 | +static void fill_prot_v3_hw(struct scsi_cmnd *scsi_cmnd, |
|---|
| 1141 | + struct hisi_sas_protect_iu_v3_hw *prot) |
|---|
| 1142 | +{ |
|---|
| 1143 | + unsigned char prot_op = scsi_get_prot_op(scsi_cmnd); |
|---|
| 1144 | + unsigned int interval = scsi_prot_interval(scsi_cmnd); |
|---|
| 1145 | + u32 lbrt_chk_val = t10_pi_ref_tag(scsi_cmnd->request); |
|---|
| 1146 | + |
|---|
| 1147 | + switch (prot_op) { |
|---|
| 1148 | + case SCSI_PROT_READ_INSERT: |
|---|
| 1149 | + prot->dw0 |= T10_INSRT_EN_MSK; |
|---|
| 1150 | + prot->lbrtgv = lbrt_chk_val; |
|---|
| 1151 | + break; |
|---|
| 1152 | + case SCSI_PROT_READ_STRIP: |
|---|
| 1153 | + prot->dw0 |= (T10_RMV_EN_MSK | T10_CHK_EN_MSK); |
|---|
| 1154 | + prot->lbrtcv = lbrt_chk_val; |
|---|
| 1155 | + prot->dw4 |= get_prot_chk_msk_v3_hw(scsi_cmnd); |
|---|
| 1156 | + break; |
|---|
| 1157 | + case SCSI_PROT_READ_PASS: |
|---|
| 1158 | + prot->dw0 |= T10_CHK_EN_MSK; |
|---|
| 1159 | + prot->lbrtcv = lbrt_chk_val; |
|---|
| 1160 | + prot->dw4 |= get_prot_chk_msk_v3_hw(scsi_cmnd); |
|---|
| 1161 | + break; |
|---|
| 1162 | + case SCSI_PROT_WRITE_INSERT: |
|---|
| 1163 | + prot->dw0 |= T10_INSRT_EN_MSK; |
|---|
| 1164 | + prot->lbrtgv = lbrt_chk_val; |
|---|
| 1165 | + break; |
|---|
| 1166 | + case SCSI_PROT_WRITE_STRIP: |
|---|
| 1167 | + prot->dw0 |= (T10_RMV_EN_MSK | T10_CHK_EN_MSK); |
|---|
| 1168 | + prot->lbrtcv = lbrt_chk_val; |
|---|
| 1169 | + break; |
|---|
| 1170 | + case SCSI_PROT_WRITE_PASS: |
|---|
| 1171 | + prot->dw0 |= T10_CHK_EN_MSK; |
|---|
| 1172 | + prot->lbrtcv = lbrt_chk_val; |
|---|
| 1173 | + prot->dw4 |= get_prot_chk_msk_v3_hw(scsi_cmnd); |
|---|
| 1174 | + break; |
|---|
| 1175 | + default: |
|---|
| 1176 | + WARN(1, "prot_op(0x%x) is not valid\n", prot_op); |
|---|
| 1177 | + break; |
|---|
| 1178 | + } |
|---|
| 1179 | + |
|---|
| 1180 | + switch (interval) { |
|---|
| 1181 | + case 512: |
|---|
| 1182 | + break; |
|---|
| 1183 | + case 4096: |
|---|
| 1184 | + prot->dw0 |= (0x1 << USR_DATA_BLOCK_SZ_OFF); |
|---|
| 1185 | + break; |
|---|
| 1186 | + case 520: |
|---|
| 1187 | + prot->dw0 |= (0x2 << USR_DATA_BLOCK_SZ_OFF); |
|---|
| 1188 | + break; |
|---|
| 1189 | + default: |
|---|
| 1190 | + WARN(1, "protection interval (0x%x) invalid\n", |
|---|
| 1191 | + interval); |
|---|
| 1192 | + break; |
|---|
| 1193 | + } |
|---|
| 1194 | + |
|---|
| 1195 | + prot->dw0 |= INCR_LBRT_MSK; |
|---|
| 930 | 1196 | } |
|---|
| 931 | 1197 | |
|---|
| 932 | 1198 | static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba, |
|---|
| .. | .. |
|---|
| 941 | 1207 | struct scsi_cmnd *scsi_cmnd = ssp_task->cmd; |
|---|
| 942 | 1208 | struct hisi_sas_tmf_task *tmf = slot->tmf; |
|---|
| 943 | 1209 | int has_data = 0, priority = !!tmf; |
|---|
| 1210 | + unsigned char prot_op; |
|---|
| 944 | 1211 | u8 *buf_cmd; |
|---|
| 945 | | - u32 dw1 = 0, dw2 = 0; |
|---|
| 1212 | + u32 dw1 = 0, dw2 = 0, len = 0; |
|---|
| 946 | 1213 | |
|---|
| 947 | 1214 | hdr->dw0 = cpu_to_le32((1 << CMD_HDR_RESP_REPORT_OFF) | |
|---|
| 948 | 1215 | (2 << CMD_HDR_TLR_CTRL_OFF) | |
|---|
| .. | .. |
|---|
| 955 | 1222 | dw1 |= 2 << CMD_HDR_FRAME_TYPE_OFF; |
|---|
| 956 | 1223 | dw1 |= DIR_NO_DATA << CMD_HDR_DIR_OFF; |
|---|
| 957 | 1224 | } else { |
|---|
| 1225 | + prot_op = scsi_get_prot_op(scsi_cmnd); |
|---|
| 958 | 1226 | dw1 |= 1 << CMD_HDR_FRAME_TYPE_OFF; |
|---|
| 959 | 1227 | switch (scsi_cmnd->sc_data_direction) { |
|---|
| 960 | 1228 | case DMA_TO_DEVICE: |
|---|
| .. | .. |
|---|
| 972 | 1240 | |
|---|
| 973 | 1241 | /* map itct entry */ |
|---|
| 974 | 1242 | dw1 |= sas_dev->device_id << CMD_HDR_DEV_ID_OFF; |
|---|
| 975 | | - hdr->dw1 = cpu_to_le32(dw1); |
|---|
| 976 | 1243 | |
|---|
| 977 | 1244 | dw2 = (((sizeof(struct ssp_command_iu) + sizeof(struct ssp_frame_hdr) |
|---|
| 978 | 1245 | + 3) / 4) << CMD_HDR_CFL_OFF) | |
|---|
| .. | .. |
|---|
| 981 | 1248 | hdr->dw2 = cpu_to_le32(dw2); |
|---|
| 982 | 1249 | hdr->transfer_tags = cpu_to_le32(slot->idx); |
|---|
| 983 | 1250 | |
|---|
| 984 | | - if (has_data) |
|---|
| 1251 | + if (has_data) { |
|---|
| 985 | 1252 | prep_prd_sge_v3_hw(hisi_hba, slot, hdr, task->scatter, |
|---|
| 986 | | - slot->n_elem); |
|---|
| 1253 | + slot->n_elem); |
|---|
| 987 | 1254 | |
|---|
| 988 | | - hdr->data_transfer_len = cpu_to_le32(task->total_xfer_len); |
|---|
| 1255 | + if (scsi_prot_sg_count(scsi_cmnd)) |
|---|
| 1256 | + prep_prd_sge_dif_v3_hw(hisi_hba, slot, hdr, |
|---|
| 1257 | + scsi_prot_sglist(scsi_cmnd), |
|---|
| 1258 | + slot->n_elem_dif); |
|---|
| 1259 | + } |
|---|
| 1260 | + |
|---|
| 989 | 1261 | hdr->cmd_table_addr = cpu_to_le64(hisi_sas_cmd_hdr_addr_dma(slot)); |
|---|
| 990 | 1262 | hdr->sts_buffer_addr = cpu_to_le64(hisi_sas_status_buf_addr_dma(slot)); |
|---|
| 991 | 1263 | |
|---|
| .. | .. |
|---|
| 1010 | 1282 | break; |
|---|
| 1011 | 1283 | } |
|---|
| 1012 | 1284 | } |
|---|
| 1285 | + |
|---|
| 1286 | + if (has_data && (prot_op != SCSI_PROT_NORMAL)) { |
|---|
| 1287 | + struct hisi_sas_protect_iu_v3_hw prot; |
|---|
| 1288 | + u8 *buf_cmd_prot; |
|---|
| 1289 | + |
|---|
| 1290 | + hdr->dw7 |= cpu_to_le32(1 << CMD_HDR_ADDR_MODE_SEL_OFF); |
|---|
| 1291 | + dw1 |= CMD_HDR_PIR_MSK; |
|---|
| 1292 | + buf_cmd_prot = hisi_sas_cmd_hdr_addr_mem(slot) + |
|---|
| 1293 | + sizeof(struct ssp_frame_hdr) + |
|---|
| 1294 | + sizeof(struct ssp_command_iu); |
|---|
| 1295 | + |
|---|
| 1296 | + memset(&prot, 0, sizeof(struct hisi_sas_protect_iu_v3_hw)); |
|---|
| 1297 | + fill_prot_v3_hw(scsi_cmnd, &prot); |
|---|
| 1298 | + memcpy(buf_cmd_prot, &prot, |
|---|
| 1299 | + sizeof(struct hisi_sas_protect_iu_v3_hw)); |
|---|
| 1300 | + /* |
|---|
| 1301 | + * For READ, we need length of info read to memory, while for |
|---|
| 1302 | + * WRITE we need length of data written to the disk. |
|---|
| 1303 | + */ |
|---|
| 1304 | + if (prot_op == SCSI_PROT_WRITE_INSERT || |
|---|
| 1305 | + prot_op == SCSI_PROT_READ_INSERT || |
|---|
| 1306 | + prot_op == SCSI_PROT_WRITE_PASS || |
|---|
| 1307 | + prot_op == SCSI_PROT_READ_PASS) { |
|---|
| 1308 | + unsigned int interval = scsi_prot_interval(scsi_cmnd); |
|---|
| 1309 | + unsigned int ilog2_interval = ilog2(interval); |
|---|
| 1310 | + |
|---|
| 1311 | + len = (task->total_xfer_len >> ilog2_interval) * 8; |
|---|
| 1312 | + } |
|---|
| 1313 | + } |
|---|
| 1314 | + |
|---|
| 1315 | + hdr->dw1 = cpu_to_le32(dw1); |
|---|
| 1316 | + |
|---|
| 1317 | + hdr->data_transfer_len = cpu_to_le32(task->total_xfer_len + len); |
|---|
| 1013 | 1318 | } |
|---|
| 1014 | 1319 | |
|---|
| 1015 | 1320 | static void prep_smp_v3_hw(struct hisi_hba *hisi_hba, |
|---|
| .. | .. |
|---|
| 1049 | 1354 | |
|---|
| 1050 | 1355 | hdr->cmd_table_addr = cpu_to_le64(req_dma_addr); |
|---|
| 1051 | 1356 | hdr->sts_buffer_addr = cpu_to_le64(hisi_sas_status_buf_addr_dma(slot)); |
|---|
| 1052 | | - |
|---|
| 1053 | 1357 | } |
|---|
| 1054 | 1358 | |
|---|
| 1055 | 1359 | static void prep_ata_v3_hw(struct hisi_hba *hisi_hba, |
|---|
| .. | .. |
|---|
| 1067 | 1371 | u32 dw1 = 0, dw2 = 0; |
|---|
| 1068 | 1372 | |
|---|
| 1069 | 1373 | hdr->dw0 = cpu_to_le32(port->id << CMD_HDR_PORT_OFF); |
|---|
| 1070 | | - if (parent_dev && DEV_IS_EXPANDER(parent_dev->dev_type)) |
|---|
| 1374 | + if (parent_dev && dev_is_expander(parent_dev->dev_type)) |
|---|
| 1071 | 1375 | hdr->dw0 |= cpu_to_le32(3 << CMD_HDR_CMD_OFF); |
|---|
| 1072 | 1376 | else |
|---|
| 1073 | | - hdr->dw0 |= cpu_to_le32(4 << CMD_HDR_CMD_OFF); |
|---|
| 1377 | + hdr->dw0 |= cpu_to_le32(4U << CMD_HDR_CMD_OFF); |
|---|
| 1074 | 1378 | |
|---|
| 1075 | 1379 | switch (task->data_dir) { |
|---|
| 1076 | 1380 | case DMA_TO_DEVICE: |
|---|
| .. | .. |
|---|
| 1100 | 1404 | hdr->dw1 = cpu_to_le32(dw1); |
|---|
| 1101 | 1405 | |
|---|
| 1102 | 1406 | /* dw2 */ |
|---|
| 1103 | | - if (task->ata_task.use_ncq && hisi_sas_get_ncq_tag(task, &hdr_tag)) { |
|---|
| 1407 | + if (task->ata_task.use_ncq) { |
|---|
| 1408 | + struct ata_queued_cmd *qc = task->uldd_task; |
|---|
| 1409 | + |
|---|
| 1410 | + hdr_tag = qc->tag; |
|---|
| 1104 | 1411 | task->ata_task.fis.sector_count |= (u8) (hdr_tag << 3); |
|---|
| 1105 | 1412 | dw2 |= hdr_tag << CMD_HDR_NCQ_TAG_OFF; |
|---|
| 1106 | 1413 | } |
|---|
| .. | .. |
|---|
| 1138 | 1445 | struct hisi_sas_port *port = slot->port; |
|---|
| 1139 | 1446 | |
|---|
| 1140 | 1447 | /* dw0 */ |
|---|
| 1141 | | - hdr->dw0 = cpu_to_le32((5 << CMD_HDR_CMD_OFF) | /*abort*/ |
|---|
| 1448 | + hdr->dw0 = cpu_to_le32((5U << CMD_HDR_CMD_OFF) | /*abort*/ |
|---|
| 1142 | 1449 | (port->id << CMD_HDR_PORT_OFF) | |
|---|
| 1143 | 1450 | (dev_is_sata(dev) |
|---|
| 1144 | 1451 | << CMD_HDR_ABORT_DEVICE_TYPE_OFF) | |
|---|
| .. | .. |
|---|
| 1152 | 1459 | /* dw7 */ |
|---|
| 1153 | 1460 | hdr->dw7 = cpu_to_le32(tag_to_abort << CMD_HDR_ABORT_IPTT_OFF); |
|---|
| 1154 | 1461 | hdr->transfer_tags = cpu_to_le32(slot->idx); |
|---|
| 1155 | | - |
|---|
| 1156 | 1462 | } |
|---|
| 1157 | 1463 | |
|---|
| 1158 | 1464 | static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba) |
|---|
| 1159 | 1465 | { |
|---|
| 1160 | | - int i, res; |
|---|
| 1466 | + int i; |
|---|
| 1467 | + irqreturn_t res; |
|---|
| 1161 | 1468 | u32 context, port_id, link_rate; |
|---|
| 1162 | 1469 | struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; |
|---|
| 1163 | 1470 | struct asd_sas_phy *sas_phy = &phy->sas_phy; |
|---|
| 1164 | 1471 | struct device *dev = hisi_hba->dev; |
|---|
| 1165 | 1472 | unsigned long flags; |
|---|
| 1166 | 1473 | |
|---|
| 1474 | + del_timer(&phy->timer); |
|---|
| 1167 | 1475 | hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 1); |
|---|
| 1168 | 1476 | |
|---|
| 1169 | 1477 | port_id = hisi_sas_read32(hisi_hba, PHY_PORT_NUM_MA); |
|---|
| .. | .. |
|---|
| 1185 | 1493 | struct hisi_sas_initial_fis *initial_fis; |
|---|
| 1186 | 1494 | struct dev_to_host_fis *fis; |
|---|
| 1187 | 1495 | u8 attached_sas_addr[SAS_ADDR_SIZE] = {0}; |
|---|
| 1496 | + struct Scsi_Host *shost = hisi_hba->shost; |
|---|
| 1188 | 1497 | |
|---|
| 1189 | 1498 | dev_info(dev, "phyup: phy%d link_rate=%d(sata)\n", phy_no, link_rate); |
|---|
| 1190 | 1499 | initial_fis = &hisi_hba->initial_fis[phy_no]; |
|---|
| .. | .. |
|---|
| 1201 | 1510 | |
|---|
| 1202 | 1511 | sas_phy->oob_mode = SATA_OOB_MODE; |
|---|
| 1203 | 1512 | attached_sas_addr[0] = 0x50; |
|---|
| 1513 | + attached_sas_addr[6] = shost->host_no; |
|---|
| 1204 | 1514 | attached_sas_addr[7] = phy_no; |
|---|
| 1205 | 1515 | memcpy(sas_phy->attached_sas_addr, |
|---|
| 1206 | 1516 | attached_sas_addr, |
|---|
| .. | .. |
|---|
| 1257 | 1567 | |
|---|
| 1258 | 1568 | static irqreturn_t phy_down_v3_hw(int phy_no, struct hisi_hba *hisi_hba) |
|---|
| 1259 | 1569 | { |
|---|
| 1570 | + struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; |
|---|
| 1260 | 1571 | u32 phy_state, sl_ctrl, txid_auto; |
|---|
| 1261 | 1572 | struct device *dev = hisi_hba->dev; |
|---|
| 1262 | 1573 | |
|---|
| 1574 | + atomic_inc(&phy->down_cnt); |
|---|
| 1575 | + |
|---|
| 1576 | + del_timer(&phy->timer); |
|---|
| 1263 | 1577 | hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_NOT_RDY_MSK, 1); |
|---|
| 1264 | 1578 | |
|---|
| 1265 | 1579 | phy_state = hisi_sas_read32(hisi_hba, PHY_STATE); |
|---|
| .. | .. |
|---|
| 1284 | 1598 | { |
|---|
| 1285 | 1599 | struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; |
|---|
| 1286 | 1600 | struct asd_sas_phy *sas_phy = &phy->sas_phy; |
|---|
| 1287 | | - struct sas_ha_struct *sas_ha = &hisi_hba->sha; |
|---|
| 1288 | 1601 | u32 bcast_status; |
|---|
| 1289 | 1602 | |
|---|
| 1290 | 1603 | hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 1); |
|---|
| 1291 | 1604 | bcast_status = hisi_sas_phy_read32(hisi_hba, phy_no, RX_PRIMS_STATUS); |
|---|
| 1292 | 1605 | if ((bcast_status & RX_BCAST_CHG_MSK) && |
|---|
| 1293 | 1606 | !test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) |
|---|
| 1294 | | - sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); |
|---|
| 1607 | + sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); |
|---|
| 1295 | 1608 | hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, |
|---|
| 1296 | 1609 | CHL_INT0_SL_RX_BCST_ACK_MSK); |
|---|
| 1297 | 1610 | hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 0); |
|---|
| .. | .. |
|---|
| 1343 | 1656 | |
|---|
| 1344 | 1657 | static const struct hisi_sas_hw_error port_axi_error[] = { |
|---|
| 1345 | 1658 | { |
|---|
| 1659 | + .irq_msk = BIT(CHL_INT1_DMAC_TX_ECC_MB_ERR_OFF), |
|---|
| 1660 | + .msg = "dmac_tx_ecc_bad_err", |
|---|
| 1661 | + }, |
|---|
| 1662 | + { |
|---|
| 1663 | + .irq_msk = BIT(CHL_INT1_DMAC_RX_ECC_MB_ERR_OFF), |
|---|
| 1664 | + .msg = "dmac_rx_ecc_bad_err", |
|---|
| 1665 | + }, |
|---|
| 1666 | + { |
|---|
| 1346 | 1667 | .irq_msk = BIT(CHL_INT1_DMAC_TX_AXI_WR_ERR_OFF), |
|---|
| 1347 | 1668 | .msg = "dma_tx_axi_wr_err", |
|---|
| 1348 | 1669 | }, |
|---|
| .. | .. |
|---|
| 1357 | 1678 | { |
|---|
| 1358 | 1679 | .irq_msk = BIT(CHL_INT1_DMAC_RX_AXI_RD_ERR_OFF), |
|---|
| 1359 | 1680 | .msg = "dma_rx_axi_rd_err", |
|---|
| 1681 | + }, |
|---|
| 1682 | + { |
|---|
| 1683 | + .irq_msk = BIT(CHL_INT1_DMAC_TX_FIFO_ERR_OFF), |
|---|
| 1684 | + .msg = "dma_tx_fifo_err", |
|---|
| 1685 | + }, |
|---|
| 1686 | + { |
|---|
| 1687 | + .irq_msk = BIT(CHL_INT1_DMAC_RX_FIFO_ERR_OFF), |
|---|
| 1688 | + .msg = "dma_rx_fifo_err", |
|---|
| 1689 | + }, |
|---|
| 1690 | + { |
|---|
| 1691 | + .irq_msk = BIT(CHL_INT1_DMAC_TX_AXI_RUSER_ERR_OFF), |
|---|
| 1692 | + .msg = "dma_tx_axi_ruser_err", |
|---|
| 1693 | + }, |
|---|
| 1694 | + { |
|---|
| 1695 | + .irq_msk = BIT(CHL_INT1_DMAC_RX_AXI_RUSER_ERR_OFF), |
|---|
| 1696 | + .msg = "dma_rx_axi_ruser_err", |
|---|
| 1360 | 1697 | }, |
|---|
| 1361 | 1698 | }; |
|---|
| 1362 | 1699 | |
|---|
| .. | .. |
|---|
| 1385 | 1722 | hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT1, irq_value); |
|---|
| 1386 | 1723 | } |
|---|
| 1387 | 1724 | |
|---|
| 1725 | +static void phy_get_events_v3_hw(struct hisi_hba *hisi_hba, int phy_no) |
|---|
| 1726 | +{ |
|---|
| 1727 | + struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; |
|---|
| 1728 | + struct asd_sas_phy *sas_phy = &phy->sas_phy; |
|---|
| 1729 | + struct sas_phy *sphy = sas_phy->phy; |
|---|
| 1730 | + unsigned long flags; |
|---|
| 1731 | + u32 reg_value; |
|---|
| 1732 | + |
|---|
| 1733 | + spin_lock_irqsave(&phy->lock, flags); |
|---|
| 1734 | + |
|---|
| 1735 | + /* loss dword sync */ |
|---|
| 1736 | + reg_value = hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_DWS_LOST); |
|---|
| 1737 | + sphy->loss_of_dword_sync_count += reg_value; |
|---|
| 1738 | + |
|---|
| 1739 | + /* phy reset problem */ |
|---|
| 1740 | + reg_value = hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_RESET_PROB); |
|---|
| 1741 | + sphy->phy_reset_problem_count += reg_value; |
|---|
| 1742 | + |
|---|
| 1743 | + /* invalid dword */ |
|---|
| 1744 | + reg_value = hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_INVLD_DW); |
|---|
| 1745 | + sphy->invalid_dword_count += reg_value; |
|---|
| 1746 | + |
|---|
| 1747 | + /* disparity err */ |
|---|
| 1748 | + reg_value = hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_DISP_ERR); |
|---|
| 1749 | + sphy->running_disparity_error_count += reg_value; |
|---|
| 1750 | + |
|---|
| 1751 | + /* code violation error */ |
|---|
| 1752 | + reg_value = hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_CODE_ERR); |
|---|
| 1753 | + phy->code_violation_err_count += reg_value; |
|---|
| 1754 | + |
|---|
| 1755 | + spin_unlock_irqrestore(&phy->lock, flags); |
|---|
| 1756 | +} |
|---|
| 1757 | + |
|---|
| 1388 | 1758 | static void handle_chl_int2_v3_hw(struct hisi_hba *hisi_hba, int phy_no) |
|---|
| 1389 | 1759 | { |
|---|
| 1390 | 1760 | u32 irq_msk = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT2_MSK); |
|---|
| .. | .. |
|---|
| 1392 | 1762 | struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; |
|---|
| 1393 | 1763 | struct pci_dev *pci_dev = hisi_hba->pci_dev; |
|---|
| 1394 | 1764 | struct device *dev = hisi_hba->dev; |
|---|
| 1765 | + static const u32 msk = BIT(CHL_INT2_RX_DISP_ERR_OFF) | |
|---|
| 1766 | + BIT(CHL_INT2_RX_CODE_ERR_OFF) | |
|---|
| 1767 | + BIT(CHL_INT2_RX_INVLD_DW_OFF); |
|---|
| 1395 | 1768 | |
|---|
| 1396 | 1769 | irq_value &= ~irq_msk; |
|---|
| 1397 | 1770 | if (!irq_value) |
|---|
| .. | .. |
|---|
| 1412 | 1785 | hisi_sas_notify_phy_event(phy, HISI_PHYE_LINK_RESET); |
|---|
| 1413 | 1786 | } |
|---|
| 1414 | 1787 | |
|---|
| 1788 | + if (pci_dev->revision > 0x20 && (irq_value & msk)) { |
|---|
| 1789 | + struct asd_sas_phy *sas_phy = &phy->sas_phy; |
|---|
| 1790 | + struct sas_phy *sphy = sas_phy->phy; |
|---|
| 1791 | + |
|---|
| 1792 | + phy_get_events_v3_hw(hisi_hba, phy_no); |
|---|
| 1793 | + |
|---|
| 1794 | + if (irq_value & BIT(CHL_INT2_RX_INVLD_DW_OFF)) |
|---|
| 1795 | + dev_info(dev, "phy%d invalid dword cnt: %u\n", phy_no, |
|---|
| 1796 | + sphy->invalid_dword_count); |
|---|
| 1797 | + |
|---|
| 1798 | + if (irq_value & BIT(CHL_INT2_RX_CODE_ERR_OFF)) |
|---|
| 1799 | + dev_info(dev, "phy%d code violation cnt: %u\n", phy_no, |
|---|
| 1800 | + phy->code_violation_err_count); |
|---|
| 1801 | + |
|---|
| 1802 | + if (irq_value & BIT(CHL_INT2_RX_DISP_ERR_OFF)) |
|---|
| 1803 | + dev_info(dev, "phy%d disparity error cnt: %u\n", phy_no, |
|---|
| 1804 | + sphy->running_disparity_error_count); |
|---|
| 1805 | + } |
|---|
| 1806 | + |
|---|
| 1415 | 1807 | if ((irq_value & BIT(CHL_INT2_RX_INVLD_DW_OFF)) && |
|---|
| 1416 | 1808 | (pci_dev->revision == 0x20)) { |
|---|
| 1417 | 1809 | u32 reg_value; |
|---|
| .. | .. |
|---|
| 1428 | 1820 | hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2, irq_value); |
|---|
| 1429 | 1821 | } |
|---|
| 1430 | 1822 | |
|---|
| 1823 | +static void handle_chl_int0_v3_hw(struct hisi_hba *hisi_hba, int phy_no) |
|---|
| 1824 | +{ |
|---|
| 1825 | + u32 irq_value0 = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT0); |
|---|
| 1826 | + |
|---|
| 1827 | + if (irq_value0 & CHL_INT0_PHY_RDY_MSK) |
|---|
| 1828 | + hisi_sas_phy_oob_ready(hisi_hba, phy_no); |
|---|
| 1829 | + |
|---|
| 1830 | + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, |
|---|
| 1831 | + irq_value0 & (~CHL_INT0_SL_RX_BCST_ACK_MSK) |
|---|
| 1832 | + & (~CHL_INT0_SL_PHY_ENABLE_MSK) |
|---|
| 1833 | + & (~CHL_INT0_NOT_RDY_MSK)); |
|---|
| 1834 | +} |
|---|
| 1835 | + |
|---|
| 1431 | 1836 | static irqreturn_t int_chnl_int_v3_hw(int irq_no, void *p) |
|---|
| 1432 | 1837 | { |
|---|
| 1433 | 1838 | struct hisi_hba *hisi_hba = p; |
|---|
| .. | .. |
|---|
| 1435 | 1840 | int phy_no = 0; |
|---|
| 1436 | 1841 | |
|---|
| 1437 | 1842 | irq_msk = hisi_sas_read32(hisi_hba, CHNL_INT_STATUS) |
|---|
| 1438 | | - & 0xeeeeeeee; |
|---|
| 1843 | + & CHNL_INT_STS_MSK; |
|---|
| 1439 | 1844 | |
|---|
| 1440 | 1845 | while (irq_msk) { |
|---|
| 1441 | | - u32 irq_value0 = hisi_sas_phy_read32(hisi_hba, phy_no, |
|---|
| 1442 | | - CHL_INT0); |
|---|
| 1846 | + if (irq_msk & (CHNL_INT_STS_INT0_MSK << (phy_no * CHNL_WIDTH))) |
|---|
| 1847 | + handle_chl_int0_v3_hw(hisi_hba, phy_no); |
|---|
| 1443 | 1848 | |
|---|
| 1444 | | - if (irq_msk & (4 << (phy_no * 4))) |
|---|
| 1849 | + if (irq_msk & (CHNL_INT_STS_INT1_MSK << (phy_no * CHNL_WIDTH))) |
|---|
| 1445 | 1850 | handle_chl_int1_v3_hw(hisi_hba, phy_no); |
|---|
| 1446 | 1851 | |
|---|
| 1447 | | - if (irq_msk & (8 << (phy_no * 4))) |
|---|
| 1852 | + if (irq_msk & (CHNL_INT_STS_INT2_MSK << (phy_no * CHNL_WIDTH))) |
|---|
| 1448 | 1853 | handle_chl_int2_v3_hw(hisi_hba, phy_no); |
|---|
| 1449 | 1854 | |
|---|
| 1450 | | - if (irq_msk & (2 << (phy_no * 4)) && irq_value0) { |
|---|
| 1451 | | - hisi_sas_phy_write32(hisi_hba, phy_no, |
|---|
| 1452 | | - CHL_INT0, irq_value0 |
|---|
| 1453 | | - & (~CHL_INT0_SL_RX_BCST_ACK_MSK) |
|---|
| 1454 | | - & (~CHL_INT0_SL_PHY_ENABLE_MSK) |
|---|
| 1455 | | - & (~CHL_INT0_NOT_RDY_MSK)); |
|---|
| 1456 | | - } |
|---|
| 1457 | | - irq_msk &= ~(0xe << (phy_no * 4)); |
|---|
| 1855 | + irq_msk &= ~(CHNL_INT_STS_PHY_MSK << (phy_no * CHNL_WIDTH)); |
|---|
| 1458 | 1856 | phy_no++; |
|---|
| 1459 | 1857 | } |
|---|
| 1460 | 1858 | |
|---|
| 1461 | 1859 | return IRQ_HANDLED; |
|---|
| 1860 | +} |
|---|
| 1861 | + |
|---|
| 1862 | +static const struct hisi_sas_hw_error multi_bit_ecc_errors[] = { |
|---|
| 1863 | + { |
|---|
| 1864 | + .irq_msk = BIT(SAS_ECC_INTR_DQE_ECC_MB_OFF), |
|---|
| 1865 | + .msk = HGC_DQE_ECC_MB_ADDR_MSK, |
|---|
| 1866 | + .shift = HGC_DQE_ECC_MB_ADDR_OFF, |
|---|
| 1867 | + .msg = "hgc_dqe_eccbad_intr", |
|---|
| 1868 | + .reg = HGC_DQE_ECC_ADDR, |
|---|
| 1869 | + }, |
|---|
| 1870 | + { |
|---|
| 1871 | + .irq_msk = BIT(SAS_ECC_INTR_IOST_ECC_MB_OFF), |
|---|
| 1872 | + .msk = HGC_IOST_ECC_MB_ADDR_MSK, |
|---|
| 1873 | + .shift = HGC_IOST_ECC_MB_ADDR_OFF, |
|---|
| 1874 | + .msg = "hgc_iost_eccbad_intr", |
|---|
| 1875 | + .reg = HGC_IOST_ECC_ADDR, |
|---|
| 1876 | + }, |
|---|
| 1877 | + { |
|---|
| 1878 | + .irq_msk = BIT(SAS_ECC_INTR_ITCT_ECC_MB_OFF), |
|---|
| 1879 | + .msk = HGC_ITCT_ECC_MB_ADDR_MSK, |
|---|
| 1880 | + .shift = HGC_ITCT_ECC_MB_ADDR_OFF, |
|---|
| 1881 | + .msg = "hgc_itct_eccbad_intr", |
|---|
| 1882 | + .reg = HGC_ITCT_ECC_ADDR, |
|---|
| 1883 | + }, |
|---|
| 1884 | + { |
|---|
| 1885 | + .irq_msk = BIT(SAS_ECC_INTR_IOSTLIST_ECC_MB_OFF), |
|---|
| 1886 | + .msk = HGC_LM_DFX_STATUS2_IOSTLIST_MSK, |
|---|
| 1887 | + .shift = HGC_LM_DFX_STATUS2_IOSTLIST_OFF, |
|---|
| 1888 | + .msg = "hgc_iostl_eccbad_intr", |
|---|
| 1889 | + .reg = HGC_LM_DFX_STATUS2, |
|---|
| 1890 | + }, |
|---|
| 1891 | + { |
|---|
| 1892 | + .irq_msk = BIT(SAS_ECC_INTR_ITCTLIST_ECC_MB_OFF), |
|---|
| 1893 | + .msk = HGC_LM_DFX_STATUS2_ITCTLIST_MSK, |
|---|
| 1894 | + .shift = HGC_LM_DFX_STATUS2_ITCTLIST_OFF, |
|---|
| 1895 | + .msg = "hgc_itctl_eccbad_intr", |
|---|
| 1896 | + .reg = HGC_LM_DFX_STATUS2, |
|---|
| 1897 | + }, |
|---|
| 1898 | + { |
|---|
| 1899 | + .irq_msk = BIT(SAS_ECC_INTR_CQE_ECC_MB_OFF), |
|---|
| 1900 | + .msk = HGC_CQE_ECC_MB_ADDR_MSK, |
|---|
| 1901 | + .shift = HGC_CQE_ECC_MB_ADDR_OFF, |
|---|
| 1902 | + .msg = "hgc_cqe_eccbad_intr", |
|---|
| 1903 | + .reg = HGC_CQE_ECC_ADDR, |
|---|
| 1904 | + }, |
|---|
| 1905 | + { |
|---|
| 1906 | + .irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM0_ECC_MB_OFF), |
|---|
| 1907 | + .msk = HGC_RXM_DFX_STATUS14_MEM0_MSK, |
|---|
| 1908 | + .shift = HGC_RXM_DFX_STATUS14_MEM0_OFF, |
|---|
| 1909 | + .msg = "rxm_mem0_eccbad_intr", |
|---|
| 1910 | + .reg = HGC_RXM_DFX_STATUS14, |
|---|
| 1911 | + }, |
|---|
| 1912 | + { |
|---|
| 1913 | + .irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM1_ECC_MB_OFF), |
|---|
| 1914 | + .msk = HGC_RXM_DFX_STATUS14_MEM1_MSK, |
|---|
| 1915 | + .shift = HGC_RXM_DFX_STATUS14_MEM1_OFF, |
|---|
| 1916 | + .msg = "rxm_mem1_eccbad_intr", |
|---|
| 1917 | + .reg = HGC_RXM_DFX_STATUS14, |
|---|
| 1918 | + }, |
|---|
| 1919 | + { |
|---|
| 1920 | + .irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM2_ECC_MB_OFF), |
|---|
| 1921 | + .msk = HGC_RXM_DFX_STATUS14_MEM2_MSK, |
|---|
| 1922 | + .shift = HGC_RXM_DFX_STATUS14_MEM2_OFF, |
|---|
| 1923 | + .msg = "rxm_mem2_eccbad_intr", |
|---|
| 1924 | + .reg = HGC_RXM_DFX_STATUS14, |
|---|
| 1925 | + }, |
|---|
| 1926 | + { |
|---|
| 1927 | + .irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM3_ECC_MB_OFF), |
|---|
| 1928 | + .msk = HGC_RXM_DFX_STATUS15_MEM3_MSK, |
|---|
| 1929 | + .shift = HGC_RXM_DFX_STATUS15_MEM3_OFF, |
|---|
| 1930 | + .msg = "rxm_mem3_eccbad_intr", |
|---|
| 1931 | + .reg = HGC_RXM_DFX_STATUS15, |
|---|
| 1932 | + }, |
|---|
| 1933 | + { |
|---|
| 1934 | + .irq_msk = BIT(SAS_ECC_INTR_OOO_RAM_ECC_MB_OFF), |
|---|
| 1935 | + .msk = AM_ROB_ECC_ERR_ADDR_MSK, |
|---|
| 1936 | + .shift = AM_ROB_ECC_ERR_ADDR_OFF, |
|---|
| 1937 | + .msg = "ooo_ram_eccbad_intr", |
|---|
| 1938 | + .reg = AM_ROB_ECC_ERR_ADDR, |
|---|
| 1939 | + }, |
|---|
| 1940 | +}; |
|---|
| 1941 | + |
|---|
| 1942 | +static void multi_bit_ecc_error_process_v3_hw(struct hisi_hba *hisi_hba, |
|---|
| 1943 | + u32 irq_value) |
|---|
| 1944 | +{ |
|---|
| 1945 | + struct device *dev = hisi_hba->dev; |
|---|
| 1946 | + const struct hisi_sas_hw_error *ecc_error; |
|---|
| 1947 | + u32 val; |
|---|
| 1948 | + int i; |
|---|
| 1949 | + |
|---|
| 1950 | + for (i = 0; i < ARRAY_SIZE(multi_bit_ecc_errors); i++) { |
|---|
| 1951 | + ecc_error = &multi_bit_ecc_errors[i]; |
|---|
| 1952 | + if (irq_value & ecc_error->irq_msk) { |
|---|
| 1953 | + val = hisi_sas_read32(hisi_hba, ecc_error->reg); |
|---|
| 1954 | + val &= ecc_error->msk; |
|---|
| 1955 | + val >>= ecc_error->shift; |
|---|
| 1956 | + dev_err(dev, "%s (0x%x) found: mem addr is 0x%08X\n", |
|---|
| 1957 | + ecc_error->msg, irq_value, val); |
|---|
| 1958 | + queue_work(hisi_hba->wq, &hisi_hba->rst_work); |
|---|
| 1959 | + } |
|---|
| 1960 | + } |
|---|
| 1961 | +} |
|---|
| 1962 | + |
|---|
| 1963 | +static void fatal_ecc_int_v3_hw(struct hisi_hba *hisi_hba) |
|---|
| 1964 | +{ |
|---|
| 1965 | + u32 irq_value, irq_msk; |
|---|
| 1966 | + |
|---|
| 1967 | + irq_msk = hisi_sas_read32(hisi_hba, SAS_ECC_INTR_MSK); |
|---|
| 1968 | + hisi_sas_write32(hisi_hba, SAS_ECC_INTR_MSK, 0xffffffff); |
|---|
| 1969 | + |
|---|
| 1970 | + irq_value = hisi_sas_read32(hisi_hba, SAS_ECC_INTR); |
|---|
| 1971 | + if (irq_value) |
|---|
| 1972 | + multi_bit_ecc_error_process_v3_hw(hisi_hba, irq_value); |
|---|
| 1973 | + |
|---|
| 1974 | + hisi_sas_write32(hisi_hba, SAS_ECC_INTR, irq_value); |
|---|
| 1975 | + hisi_sas_write32(hisi_hba, SAS_ECC_INTR_MSK, irq_msk); |
|---|
| 1462 | 1976 | } |
|---|
| 1463 | 1977 | |
|---|
| 1464 | 1978 | static const struct hisi_sas_hw_error axi_error[] = { |
|---|
| .. | .. |
|---|
| 1470 | 1984 | { .msk = BIT(5), .msg = "SATA_AXI_R_ERR" }, |
|---|
| 1471 | 1985 | { .msk = BIT(6), .msg = "DQE_AXI_R_ERR" }, |
|---|
| 1472 | 1986 | { .msk = BIT(7), .msg = "CQE_AXI_W_ERR" }, |
|---|
| 1473 | | - {}, |
|---|
| 1987 | + {} |
|---|
| 1474 | 1988 | }; |
|---|
| 1475 | 1989 | |
|---|
| 1476 | 1990 | static const struct hisi_sas_hw_error fifo_error[] = { |
|---|
| .. | .. |
|---|
| 1479 | 1993 | { .msk = BIT(10), .msg = "GETDQE_FIFO" }, |
|---|
| 1480 | 1994 | { .msk = BIT(11), .msg = "CMDP_FIFO" }, |
|---|
| 1481 | 1995 | { .msk = BIT(12), .msg = "AWTCTRL_FIFO" }, |
|---|
| 1482 | | - {}, |
|---|
| 1996 | + {} |
|---|
| 1483 | 1997 | }; |
|---|
| 1484 | 1998 | |
|---|
| 1485 | 1999 | static const struct hisi_sas_hw_error fatal_axi_error[] = { |
|---|
| .. | .. |
|---|
| 1513 | 2027 | .irq_msk = BIT(ENT_INT_SRC3_ABT_OFF), |
|---|
| 1514 | 2028 | .msg = "SAS_HGC_ABT fetch LM list", |
|---|
| 1515 | 2029 | }, |
|---|
| 2030 | + { |
|---|
| 2031 | + .irq_msk = BIT(ENT_INT_SRC3_DQE_POISON_OFF), |
|---|
| 2032 | + .msg = "read dqe poison", |
|---|
| 2033 | + }, |
|---|
| 2034 | + { |
|---|
| 2035 | + .irq_msk = BIT(ENT_INT_SRC3_IOST_POISON_OFF), |
|---|
| 2036 | + .msg = "read iost poison", |
|---|
| 2037 | + }, |
|---|
| 2038 | + { |
|---|
| 2039 | + .irq_msk = BIT(ENT_INT_SRC3_ITCT_POISON_OFF), |
|---|
| 2040 | + .msg = "read itct poison", |
|---|
| 2041 | + }, |
|---|
| 2042 | + { |
|---|
| 2043 | + .irq_msk = BIT(ENT_INT_SRC3_ITCT_NCQ_POISON_OFF), |
|---|
| 2044 | + .msg = "read itct ncq poison", |
|---|
| 2045 | + }, |
|---|
| 2046 | + |
|---|
| 1516 | 2047 | }; |
|---|
| 1517 | 2048 | |
|---|
| 1518 | 2049 | static irqreturn_t fatal_axi_int_v3_hw(int irq_no, void *p) |
|---|
| .. | .. |
|---|
| 1565 | 2096 | } |
|---|
| 1566 | 2097 | } |
|---|
| 1567 | 2098 | |
|---|
| 2099 | + fatal_ecc_int_v3_hw(hisi_hba); |
|---|
| 2100 | + |
|---|
| 1568 | 2101 | if (irq_value & BIT(ENT_INT_SRC3_ITC_INT_OFF)) { |
|---|
| 1569 | 2102 | u32 reg_val = hisi_sas_read32(hisi_hba, ITCT_CLR); |
|---|
| 1570 | 2103 | u32 dev_id = reg_val & ITCT_DEV_MSK; |
|---|
| .. | .. |
|---|
| 1593 | 2126 | &complete_queue[slot->cmplt_queue_slot]; |
|---|
| 1594 | 2127 | struct hisi_sas_err_record_v3 *record = |
|---|
| 1595 | 2128 | hisi_sas_status_buf_addr_mem(slot); |
|---|
| 1596 | | - u32 dma_rx_err_type = record->dma_rx_err_type; |
|---|
| 1597 | | - u32 trans_tx_fail_type = record->trans_tx_fail_type; |
|---|
| 2129 | + u32 dma_rx_err_type = le32_to_cpu(record->dma_rx_err_type); |
|---|
| 2130 | + u32 trans_tx_fail_type = le32_to_cpu(record->trans_tx_fail_type); |
|---|
| 2131 | + u32 dw3 = le32_to_cpu(complete_hdr->dw3); |
|---|
| 1598 | 2132 | |
|---|
| 1599 | 2133 | switch (task->task_proto) { |
|---|
| 1600 | 2134 | case SAS_PROTOCOL_SSP: |
|---|
| 1601 | 2135 | if (dma_rx_err_type & RX_DATA_LEN_UNDERFLOW_MSK) { |
|---|
| 1602 | 2136 | ts->residual = trans_tx_fail_type; |
|---|
| 1603 | 2137 | ts->stat = SAS_DATA_UNDERRUN; |
|---|
| 1604 | | - } else if (complete_hdr->dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) { |
|---|
| 2138 | + } else if (dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) { |
|---|
| 1605 | 2139 | ts->stat = SAS_QUEUE_FULL; |
|---|
| 1606 | 2140 | slot->abort = 1; |
|---|
| 1607 | 2141 | } else { |
|---|
| .. | .. |
|---|
| 1615 | 2149 | if (dma_rx_err_type & RX_DATA_LEN_UNDERFLOW_MSK) { |
|---|
| 1616 | 2150 | ts->residual = trans_tx_fail_type; |
|---|
| 1617 | 2151 | ts->stat = SAS_DATA_UNDERRUN; |
|---|
| 1618 | | - } else if (complete_hdr->dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) { |
|---|
| 2152 | + } else if (dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) { |
|---|
| 1619 | 2153 | ts->stat = SAS_PHY_DOWN; |
|---|
| 1620 | 2154 | slot->abort = 1; |
|---|
| 1621 | 2155 | } else { |
|---|
| .. | .. |
|---|
| 1632 | 2166 | } |
|---|
| 1633 | 2167 | } |
|---|
| 1634 | 2168 | |
|---|
| 1635 | | -static int |
|---|
| 1636 | | -slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) |
|---|
| 2169 | +static void slot_complete_v3_hw(struct hisi_hba *hisi_hba, |
|---|
| 2170 | + struct hisi_sas_slot *slot) |
|---|
| 1637 | 2171 | { |
|---|
| 1638 | 2172 | struct sas_task *task = slot->task; |
|---|
| 1639 | 2173 | struct hisi_sas_device *sas_dev; |
|---|
| .. | .. |
|---|
| 1641 | 2175 | struct task_status_struct *ts; |
|---|
| 1642 | 2176 | struct domain_device *device; |
|---|
| 1643 | 2177 | struct sas_ha_struct *ha; |
|---|
| 1644 | | - enum exec_status sts; |
|---|
| 1645 | 2178 | struct hisi_sas_complete_v3_hdr *complete_queue = |
|---|
| 1646 | 2179 | hisi_hba->complete_hdr[slot->cmplt_queue]; |
|---|
| 1647 | 2180 | struct hisi_sas_complete_v3_hdr *complete_hdr = |
|---|
| 1648 | 2181 | &complete_queue[slot->cmplt_queue_slot]; |
|---|
| 1649 | 2182 | unsigned long flags; |
|---|
| 1650 | 2183 | bool is_internal = slot->is_internal; |
|---|
| 2184 | + u32 dw0, dw1, dw3; |
|---|
| 1651 | 2185 | |
|---|
| 1652 | 2186 | if (unlikely(!task || !task->lldd_task || !task->dev)) |
|---|
| 1653 | | - return -EINVAL; |
|---|
| 2187 | + return; |
|---|
| 1654 | 2188 | |
|---|
| 1655 | 2189 | ts = &task->task_status; |
|---|
| 1656 | 2190 | device = task->dev; |
|---|
| .. | .. |
|---|
| 1671 | 2205 | goto out; |
|---|
| 1672 | 2206 | } |
|---|
| 1673 | 2207 | |
|---|
| 2208 | + dw0 = le32_to_cpu(complete_hdr->dw0); |
|---|
| 2209 | + dw1 = le32_to_cpu(complete_hdr->dw1); |
|---|
| 2210 | + dw3 = le32_to_cpu(complete_hdr->dw3); |
|---|
| 2211 | + |
|---|
| 1674 | 2212 | /* |
|---|
| 1675 | 2213 | * Use SAS+TMF status codes |
|---|
| 1676 | 2214 | */ |
|---|
| 1677 | | - switch ((complete_hdr->dw0 & CMPLT_HDR_ABORT_STAT_MSK) |
|---|
| 1678 | | - >> CMPLT_HDR_ABORT_STAT_OFF) { |
|---|
| 2215 | + switch ((dw0 & CMPLT_HDR_ABORT_STAT_MSK) >> CMPLT_HDR_ABORT_STAT_OFF) { |
|---|
| 1679 | 2216 | case STAT_IO_ABORTED: |
|---|
| 1680 | 2217 | /* this IO has been aborted by abort command */ |
|---|
| 1681 | 2218 | ts->stat = SAS_ABORTED_TASK; |
|---|
| .. | .. |
|---|
| 1698 | 2235 | } |
|---|
| 1699 | 2236 | |
|---|
| 1700 | 2237 | /* check for erroneous completion */ |
|---|
| 1701 | | - if ((complete_hdr->dw0 & CMPLT_HDR_CMPLT_MSK) == 0x3) { |
|---|
| 2238 | + if ((dw0 & CMPLT_HDR_CMPLT_MSK) == 0x3) { |
|---|
| 1702 | 2239 | u32 *error_info = hisi_sas_status_buf_addr_mem(slot); |
|---|
| 1703 | 2240 | |
|---|
| 1704 | 2241 | slot_err_v3_hw(hisi_hba, task, slot); |
|---|
| 1705 | 2242 | if (ts->stat != SAS_DATA_UNDERRUN) |
|---|
| 1706 | | - dev_info(dev, "erroneous completion iptt=%d task=%p dev id=%d " |
|---|
| 1707 | | - "CQ hdr: 0x%x 0x%x 0x%x 0x%x " |
|---|
| 1708 | | - "Error info: 0x%x 0x%x 0x%x 0x%x\n", |
|---|
| 1709 | | - slot->idx, task, sas_dev->device_id, |
|---|
| 1710 | | - complete_hdr->dw0, complete_hdr->dw1, |
|---|
| 1711 | | - complete_hdr->act, complete_hdr->dw3, |
|---|
| 1712 | | - error_info[0], error_info[1], |
|---|
| 1713 | | - error_info[2], error_info[3]); |
|---|
| 1714 | | - if (unlikely(slot->abort)) |
|---|
| 1715 | | - return ts->stat; |
|---|
| 2243 | + dev_info(dev, "erroneous completion iptt=%d task=%pK dev id=%d CQ hdr: 0x%x 0x%x 0x%x 0x%x Error info: 0x%x 0x%x 0x%x 0x%x\n", |
|---|
| 2244 | + slot->idx, task, sas_dev->device_id, |
|---|
| 2245 | + dw0, dw1, complete_hdr->act, dw3, |
|---|
| 2246 | + error_info[0], error_info[1], |
|---|
| 2247 | + error_info[2], error_info[3]); |
|---|
| 2248 | + if (unlikely(slot->abort)) { |
|---|
| 2249 | + sas_task_abort(task); |
|---|
| 2250 | + return; |
|---|
| 2251 | + } |
|---|
| 1716 | 2252 | goto out; |
|---|
| 1717 | 2253 | } |
|---|
| 1718 | 2254 | |
|---|
| .. | .. |
|---|
| 1727 | 2263 | } |
|---|
| 1728 | 2264 | case SAS_PROTOCOL_SMP: { |
|---|
| 1729 | 2265 | struct scatterlist *sg_resp = &task->smp_task.smp_resp; |
|---|
| 1730 | | - void *to; |
|---|
| 2266 | + void *to = page_address(sg_page(sg_resp)); |
|---|
| 1731 | 2267 | |
|---|
| 1732 | 2268 | ts->stat = SAM_STAT_GOOD; |
|---|
| 1733 | | - to = kmap_atomic(sg_page(sg_resp)); |
|---|
| 1734 | 2269 | |
|---|
| 1735 | | - dma_unmap_sg(dev, &task->smp_task.smp_resp, 1, |
|---|
| 1736 | | - DMA_FROM_DEVICE); |
|---|
| 1737 | 2270 | dma_unmap_sg(dev, &task->smp_task.smp_req, 1, |
|---|
| 1738 | 2271 | DMA_TO_DEVICE); |
|---|
| 1739 | 2272 | memcpy(to + sg_resp->offset, |
|---|
| 1740 | 2273 | hisi_sas_status_buf_addr_mem(slot) + |
|---|
| 1741 | 2274 | sizeof(struct hisi_sas_err_record), |
|---|
| 1742 | | - sg_dma_len(sg_resp)); |
|---|
| 1743 | | - kunmap_atomic(to); |
|---|
| 2275 | + sg_resp->length); |
|---|
| 1744 | 2276 | break; |
|---|
| 1745 | 2277 | } |
|---|
| 1746 | 2278 | case SAS_PROTOCOL_SATA: |
|---|
| .. | .. |
|---|
| 1761 | 2293 | } |
|---|
| 1762 | 2294 | |
|---|
| 1763 | 2295 | out: |
|---|
| 1764 | | - sts = ts->stat; |
|---|
| 1765 | 2296 | spin_lock_irqsave(&task->task_state_lock, flags); |
|---|
| 1766 | 2297 | if (task->task_state_flags & SAS_TASK_STATE_ABORTED) { |
|---|
| 1767 | 2298 | spin_unlock_irqrestore(&task->task_state_lock, flags); |
|---|
| 1768 | | - dev_info(dev, "slot complete: task(%p) aborted\n", task); |
|---|
| 1769 | | - return SAS_ABORTED_TASK; |
|---|
| 2299 | + dev_info(dev, "slot complete: task(%pK) aborted\n", task); |
|---|
| 2300 | + return; |
|---|
| 1770 | 2301 | } |
|---|
| 1771 | 2302 | task->task_state_flags |= SAS_TASK_STATE_DONE; |
|---|
| 1772 | 2303 | spin_unlock_irqrestore(&task->task_state_lock, flags); |
|---|
| .. | .. |
|---|
| 1776 | 2307 | spin_lock_irqsave(&device->done_lock, flags); |
|---|
| 1777 | 2308 | if (test_bit(SAS_HA_FROZEN, &ha->state)) { |
|---|
| 1778 | 2309 | spin_unlock_irqrestore(&device->done_lock, flags); |
|---|
| 1779 | | - dev_info(dev, "slot complete: task(%p) ignored\n ", |
|---|
| 2310 | + dev_info(dev, "slot complete: task(%pK) ignored\n ", |
|---|
| 1780 | 2311 | task); |
|---|
| 1781 | | - return sts; |
|---|
| 2312 | + return; |
|---|
| 1782 | 2313 | } |
|---|
| 1783 | 2314 | spin_unlock_irqrestore(&device->done_lock, flags); |
|---|
| 1784 | 2315 | } |
|---|
| 1785 | 2316 | |
|---|
| 1786 | 2317 | if (task->task_done) |
|---|
| 1787 | 2318 | task->task_done(task); |
|---|
| 1788 | | - |
|---|
| 1789 | | - return sts; |
|---|
| 1790 | 2319 | } |
|---|
| 1791 | 2320 | |
|---|
| 1792 | | -static void cq_tasklet_v3_hw(unsigned long val) |
|---|
| 2321 | +static irqreturn_t cq_thread_v3_hw(int irq_no, void *p) |
|---|
| 1793 | 2322 | { |
|---|
| 1794 | | - struct hisi_sas_cq *cq = (struct hisi_sas_cq *)val; |
|---|
| 2323 | + struct hisi_sas_cq *cq = p; |
|---|
| 1795 | 2324 | struct hisi_hba *hisi_hba = cq->hisi_hba; |
|---|
| 1796 | 2325 | struct hisi_sas_slot *slot; |
|---|
| 1797 | 2326 | struct hisi_sas_complete_v3_hdr *complete_queue; |
|---|
| .. | .. |
|---|
| 1806 | 2335 | while (rd_point != wr_point) { |
|---|
| 1807 | 2336 | struct hisi_sas_complete_v3_hdr *complete_hdr; |
|---|
| 1808 | 2337 | struct device *dev = hisi_hba->dev; |
|---|
| 2338 | + u32 dw1; |
|---|
| 1809 | 2339 | int iptt; |
|---|
| 1810 | 2340 | |
|---|
| 1811 | 2341 | complete_hdr = &complete_queue[rd_point]; |
|---|
| 2342 | + dw1 = le32_to_cpu(complete_hdr->dw1); |
|---|
| 1812 | 2343 | |
|---|
| 1813 | | - iptt = (complete_hdr->dw1) & CMPLT_HDR_IPTT_MSK; |
|---|
| 2344 | + iptt = dw1 & CMPLT_HDR_IPTT_MSK; |
|---|
| 1814 | 2345 | if (likely(iptt < HISI_SAS_COMMAND_ENTRIES_V3_HW)) { |
|---|
| 1815 | 2346 | slot = &hisi_hba->slot_info[iptt]; |
|---|
| 1816 | 2347 | slot->cmplt_queue_slot = rd_point; |
|---|
| .. | .. |
|---|
| 1826 | 2357 | /* update rd_point */ |
|---|
| 1827 | 2358 | cq->rd_point = rd_point; |
|---|
| 1828 | 2359 | hisi_sas_write32(hisi_hba, COMPL_Q_0_RD_PTR + (0x14 * queue), rd_point); |
|---|
| 2360 | + |
|---|
| 2361 | + return IRQ_HANDLED; |
|---|
| 1829 | 2362 | } |
|---|
| 1830 | 2363 | |
|---|
| 1831 | 2364 | static irqreturn_t cq_interrupt_v3_hw(int irq_no, void *p) |
|---|
| .. | .. |
|---|
| 1836 | 2369 | |
|---|
| 1837 | 2370 | hisi_sas_write32(hisi_hba, OQ_INT_SRC, 1 << queue); |
|---|
| 1838 | 2371 | |
|---|
| 1839 | | - tasklet_schedule(&cq->tasklet); |
|---|
| 2372 | + return IRQ_WAKE_THREAD; |
|---|
| 2373 | +} |
|---|
| 1840 | 2374 | |
|---|
| 1841 | | - return IRQ_HANDLED; |
|---|
| 2375 | +static void hisi_sas_v3_free_vectors(void *data) |
|---|
| 2376 | +{ |
|---|
| 2377 | + struct pci_dev *pdev = data; |
|---|
| 2378 | + |
|---|
| 2379 | + pci_free_irq_vectors(pdev); |
|---|
| 2380 | +} |
|---|
| 2381 | + |
|---|
| 2382 | +static int interrupt_preinit_v3_hw(struct hisi_hba *hisi_hba) |
|---|
| 2383 | +{ |
|---|
| 2384 | + int vectors; |
|---|
| 2385 | + int max_msi = HISI_SAS_MSI_COUNT_V3_HW, min_msi; |
|---|
| 2386 | + struct Scsi_Host *shost = hisi_hba->shost; |
|---|
| 2387 | + struct pci_dev *pdev = hisi_hba->pci_dev; |
|---|
| 2388 | + struct irq_affinity desc = { |
|---|
| 2389 | + .pre_vectors = BASE_VECTORS_V3_HW, |
|---|
| 2390 | + }; |
|---|
| 2391 | + |
|---|
| 2392 | + min_msi = MIN_AFFINE_VECTORS_V3_HW; |
|---|
| 2393 | + vectors = pci_alloc_irq_vectors_affinity(pdev, |
|---|
| 2394 | + min_msi, max_msi, |
|---|
| 2395 | + PCI_IRQ_MSI | |
|---|
| 2396 | + PCI_IRQ_AFFINITY, |
|---|
| 2397 | + &desc); |
|---|
| 2398 | + if (vectors < 0) |
|---|
| 2399 | + return -ENOENT; |
|---|
| 2400 | + |
|---|
| 2401 | + |
|---|
| 2402 | + hisi_hba->cq_nvecs = vectors - BASE_VECTORS_V3_HW; |
|---|
| 2403 | + shost->nr_hw_queues = hisi_hba->cq_nvecs; |
|---|
| 2404 | + |
|---|
| 2405 | + devm_add_action(&pdev->dev, hisi_sas_v3_free_vectors, pdev); |
|---|
| 2406 | + return 0; |
|---|
| 1842 | 2407 | } |
|---|
| 1843 | 2408 | |
|---|
| 1844 | 2409 | static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) |
|---|
| 1845 | 2410 | { |
|---|
| 1846 | 2411 | struct device *dev = hisi_hba->dev; |
|---|
| 1847 | 2412 | struct pci_dev *pdev = hisi_hba->pci_dev; |
|---|
| 1848 | | - int vectors, rc; |
|---|
| 1849 | | - int i, k; |
|---|
| 1850 | | - int max_msi = HISI_SAS_MSI_COUNT_V3_HW; |
|---|
| 1851 | | - |
|---|
| 1852 | | - vectors = pci_alloc_irq_vectors(hisi_hba->pci_dev, 1, |
|---|
| 1853 | | - max_msi, PCI_IRQ_MSI); |
|---|
| 1854 | | - if (vectors < max_msi) { |
|---|
| 1855 | | - dev_err(dev, "could not allocate all msi (%d)\n", vectors); |
|---|
| 1856 | | - return -ENOENT; |
|---|
| 1857 | | - } |
|---|
| 2413 | + int rc, i; |
|---|
| 1858 | 2414 | |
|---|
| 1859 | 2415 | rc = devm_request_irq(dev, pci_irq_vector(pdev, 1), |
|---|
| 1860 | 2416 | int_phy_up_down_bcast_v3_hw, 0, |
|---|
| 1861 | 2417 | DRV_NAME " phy", hisi_hba); |
|---|
| 1862 | 2418 | if (rc) { |
|---|
| 1863 | 2419 | dev_err(dev, "could not request phy interrupt, rc=%d\n", rc); |
|---|
| 1864 | | - rc = -ENOENT; |
|---|
| 1865 | | - goto free_irq_vectors; |
|---|
| 2420 | + return -ENOENT; |
|---|
| 1866 | 2421 | } |
|---|
| 1867 | 2422 | |
|---|
| 1868 | 2423 | rc = devm_request_irq(dev, pci_irq_vector(pdev, 2), |
|---|
| .. | .. |
|---|
| 1870 | 2425 | DRV_NAME " channel", hisi_hba); |
|---|
| 1871 | 2426 | if (rc) { |
|---|
| 1872 | 2427 | dev_err(dev, "could not request chnl interrupt, rc=%d\n", rc); |
|---|
| 1873 | | - rc = -ENOENT; |
|---|
| 1874 | | - goto free_phy_irq; |
|---|
| 2428 | + return -ENOENT; |
|---|
| 1875 | 2429 | } |
|---|
| 1876 | 2430 | |
|---|
| 1877 | 2431 | rc = devm_request_irq(dev, pci_irq_vector(pdev, 11), |
|---|
| .. | .. |
|---|
| 1879 | 2433 | DRV_NAME " fatal", hisi_hba); |
|---|
| 1880 | 2434 | if (rc) { |
|---|
| 1881 | 2435 | dev_err(dev, "could not request fatal interrupt, rc=%d\n", rc); |
|---|
| 1882 | | - rc = -ENOENT; |
|---|
| 1883 | | - goto free_chnl_interrupt; |
|---|
| 2436 | + return -ENOENT; |
|---|
| 1884 | 2437 | } |
|---|
| 1885 | 2438 | |
|---|
| 1886 | | - /* Init tasklets for cq only */ |
|---|
| 1887 | | - for (i = 0; i < hisi_hba->queue_count; i++) { |
|---|
| 2439 | + if (hisi_sas_intr_conv) |
|---|
| 2440 | + dev_info(dev, "Enable interrupt converge\n"); |
|---|
| 2441 | + |
|---|
| 2442 | + for (i = 0; i < hisi_hba->cq_nvecs; i++) { |
|---|
| 1888 | 2443 | struct hisi_sas_cq *cq = &hisi_hba->cq[i]; |
|---|
| 1889 | | - struct tasklet_struct *t = &cq->tasklet; |
|---|
| 2444 | + int nr = hisi_sas_intr_conv ? 16 : 16 + i; |
|---|
| 2445 | + unsigned long irqflags = hisi_sas_intr_conv ? IRQF_SHARED : |
|---|
| 2446 | + IRQF_ONESHOT; |
|---|
| 1890 | 2447 | |
|---|
| 1891 | | - rc = devm_request_irq(dev, pci_irq_vector(pdev, i+16), |
|---|
| 1892 | | - cq_interrupt_v3_hw, 0, |
|---|
| 1893 | | - DRV_NAME " cq", cq); |
|---|
| 2448 | + cq->irq_no = pci_irq_vector(pdev, nr); |
|---|
| 2449 | + rc = devm_request_threaded_irq(dev, cq->irq_no, |
|---|
| 2450 | + cq_interrupt_v3_hw, |
|---|
| 2451 | + cq_thread_v3_hw, |
|---|
| 2452 | + irqflags, |
|---|
| 2453 | + DRV_NAME " cq", cq); |
|---|
| 1894 | 2454 | if (rc) { |
|---|
| 1895 | | - dev_err(dev, |
|---|
| 1896 | | - "could not request cq%d interrupt, rc=%d\n", |
|---|
| 2455 | + dev_err(dev, "could not request cq%d interrupt, rc=%d\n", |
|---|
| 1897 | 2456 | i, rc); |
|---|
| 1898 | | - rc = -ENOENT; |
|---|
| 1899 | | - goto free_cq_irqs; |
|---|
| 2457 | + return -ENOENT; |
|---|
| 1900 | 2458 | } |
|---|
| 1901 | | - |
|---|
| 1902 | | - tasklet_init(t, cq_tasklet_v3_hw, (unsigned long)cq); |
|---|
| 2459 | + cq->irq_mask = pci_irq_get_affinity(pdev, i + BASE_VECTORS_V3_HW); |
|---|
| 2460 | + if (!cq->irq_mask) { |
|---|
| 2461 | + dev_err(dev, "could not get cq%d irq affinity!\n", i); |
|---|
| 2462 | + return -ENOENT; |
|---|
| 2463 | + } |
|---|
| 1903 | 2464 | } |
|---|
| 1904 | 2465 | |
|---|
| 1905 | 2466 | return 0; |
|---|
| 1906 | | - |
|---|
| 1907 | | -free_cq_irqs: |
|---|
| 1908 | | - for (k = 0; k < i; k++) { |
|---|
| 1909 | | - struct hisi_sas_cq *cq = &hisi_hba->cq[k]; |
|---|
| 1910 | | - |
|---|
| 1911 | | - free_irq(pci_irq_vector(pdev, k+16), cq); |
|---|
| 1912 | | - } |
|---|
| 1913 | | - free_irq(pci_irq_vector(pdev, 11), hisi_hba); |
|---|
| 1914 | | -free_chnl_interrupt: |
|---|
| 1915 | | - free_irq(pci_irq_vector(pdev, 2), hisi_hba); |
|---|
| 1916 | | -free_phy_irq: |
|---|
| 1917 | | - free_irq(pci_irq_vector(pdev, 1), hisi_hba); |
|---|
| 1918 | | -free_irq_vectors: |
|---|
| 1919 | | - pci_free_irq_vectors(pdev); |
|---|
| 1920 | | - return rc; |
|---|
| 1921 | 2467 | } |
|---|
| 1922 | 2468 | |
|---|
| 1923 | 2469 | static int hisi_sas_v3_init(struct hisi_hba *hisi_hba) |
|---|
| .. | .. |
|---|
| 1939 | 2485 | struct sas_phy_linkrates *r) |
|---|
| 1940 | 2486 | { |
|---|
| 1941 | 2487 | enum sas_linkrate max = r->maximum_linkrate; |
|---|
| 1942 | | - u32 prog_phy_link_rate = 0x800; |
|---|
| 2488 | + u32 prog_phy_link_rate = hisi_sas_phy_read32(hisi_hba, phy_no, |
|---|
| 2489 | + PROG_PHY_LINK_RATE); |
|---|
| 1943 | 2490 | |
|---|
| 2491 | + prog_phy_link_rate &= ~CFG_PROG_PHY_LINK_RATE_MSK; |
|---|
| 1944 | 2492 | prog_phy_link_rate |= hisi_sas_get_prog_phy_linkrate_mask(max); |
|---|
| 1945 | 2493 | hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE, |
|---|
| 1946 | 2494 | prog_phy_link_rate); |
|---|
| .. | .. |
|---|
| 1954 | 2502 | synchronize_irq(pci_irq_vector(pdev, 1)); |
|---|
| 1955 | 2503 | synchronize_irq(pci_irq_vector(pdev, 2)); |
|---|
| 1956 | 2504 | synchronize_irq(pci_irq_vector(pdev, 11)); |
|---|
| 1957 | | - for (i = 0; i < hisi_hba->queue_count; i++) { |
|---|
| 2505 | + for (i = 0; i < hisi_hba->queue_count; i++) |
|---|
| 1958 | 2506 | hisi_sas_write32(hisi_hba, OQ0_INT_SRC_MSK + 0x4 * i, 0x1); |
|---|
| 2507 | + |
|---|
| 2508 | + for (i = 0; i < hisi_hba->cq_nvecs; i++) |
|---|
| 1959 | 2509 | synchronize_irq(pci_irq_vector(pdev, i + 16)); |
|---|
| 1960 | | - } |
|---|
| 1961 | 2510 | |
|---|
| 1962 | 2511 | hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, 0xffffffff); |
|---|
| 1963 | 2512 | hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK2, 0xffffffff); |
|---|
| .. | .. |
|---|
| 1978 | 2527 | return hisi_sas_read32(hisi_hba, PHY_STATE); |
|---|
| 1979 | 2528 | } |
|---|
| 1980 | 2529 | |
|---|
| 1981 | | -static void phy_get_events_v3_hw(struct hisi_hba *hisi_hba, int phy_no) |
|---|
| 1982 | | -{ |
|---|
| 1983 | | - struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; |
|---|
| 1984 | | - struct asd_sas_phy *sas_phy = &phy->sas_phy; |
|---|
| 1985 | | - struct sas_phy *sphy = sas_phy->phy; |
|---|
| 1986 | | - u32 reg_value; |
|---|
| 1987 | | - |
|---|
| 1988 | | - /* loss dword sync */ |
|---|
| 1989 | | - reg_value = hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_DWS_LOST); |
|---|
| 1990 | | - sphy->loss_of_dword_sync_count += reg_value; |
|---|
| 1991 | | - |
|---|
| 1992 | | - /* phy reset problem */ |
|---|
| 1993 | | - reg_value = hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_RESET_PROB); |
|---|
| 1994 | | - sphy->phy_reset_problem_count += reg_value; |
|---|
| 1995 | | - |
|---|
| 1996 | | - /* invalid dword */ |
|---|
| 1997 | | - reg_value = hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_INVLD_DW); |
|---|
| 1998 | | - sphy->invalid_dword_count += reg_value; |
|---|
| 1999 | | - |
|---|
| 2000 | | - /* disparity err */ |
|---|
| 2001 | | - reg_value = hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_DISP_ERR); |
|---|
| 2002 | | - sphy->running_disparity_error_count += reg_value; |
|---|
| 2003 | | - |
|---|
| 2004 | | -} |
|---|
| 2005 | | - |
|---|
| 2006 | 2530 | static int disable_host_v3_hw(struct hisi_hba *hisi_hba) |
|---|
| 2007 | 2531 | { |
|---|
| 2008 | 2532 | struct device *dev = hisi_hba->dev; |
|---|
| .. | .. |
|---|
| 2011 | 2535 | |
|---|
| 2012 | 2536 | interrupt_disable_v3_hw(hisi_hba); |
|---|
| 2013 | 2537 | hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, 0x0); |
|---|
| 2014 | | - hisi_sas_kill_tasklets(hisi_hba); |
|---|
| 2015 | 2538 | |
|---|
| 2016 | 2539 | hisi_sas_stop_phys(hisi_hba); |
|---|
| 2017 | 2540 | |
|---|
| .. | .. |
|---|
| 2073 | 2596 | break; |
|---|
| 2074 | 2597 | default: |
|---|
| 2075 | 2598 | dev_err(dev, "write gpio: unsupported or bad reg type %d\n", |
|---|
| 2076 | | - reg_type); |
|---|
| 2599 | + reg_type); |
|---|
| 2077 | 2600 | return -EINVAL; |
|---|
| 2078 | 2601 | } |
|---|
| 2079 | 2602 | |
|---|
| .. | .. |
|---|
| 2095 | 2618 | msleep(delay_ms); |
|---|
| 2096 | 2619 | } |
|---|
| 2097 | 2620 | |
|---|
| 2621 | + if (time >= timeout_ms) { |
|---|
| 2622 | + dev_dbg(dev, "Wait commands complete timeout!\n"); |
|---|
| 2623 | + return; |
|---|
| 2624 | + } |
|---|
| 2625 | + |
|---|
| 2098 | 2626 | dev_dbg(dev, "wait commands complete %dms\n", time); |
|---|
| 2627 | +} |
|---|
| 2628 | + |
|---|
| 2629 | +static ssize_t intr_conv_v3_hw_show(struct device *dev, |
|---|
| 2630 | + struct device_attribute *attr, char *buf) |
|---|
| 2631 | +{ |
|---|
| 2632 | + return scnprintf(buf, PAGE_SIZE, "%u\n", hisi_sas_intr_conv); |
|---|
| 2633 | +} |
|---|
| 2634 | +static DEVICE_ATTR_RO(intr_conv_v3_hw); |
|---|
| 2635 | + |
|---|
| 2636 | +static void config_intr_coal_v3_hw(struct hisi_hba *hisi_hba) |
|---|
| 2637 | +{ |
|---|
| 2638 | + /* config those registers between enable and disable PHYs */ |
|---|
| 2639 | + hisi_sas_stop_phys(hisi_hba); |
|---|
| 2640 | + |
|---|
| 2641 | + if (hisi_hba->intr_coal_ticks == 0 || |
|---|
| 2642 | + hisi_hba->intr_coal_count == 0) { |
|---|
| 2643 | + hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x1); |
|---|
| 2644 | + hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, 0x1); |
|---|
| 2645 | + hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, 0x1); |
|---|
| 2646 | + } else { |
|---|
| 2647 | + hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x3); |
|---|
| 2648 | + hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, |
|---|
| 2649 | + hisi_hba->intr_coal_ticks); |
|---|
| 2650 | + hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, |
|---|
| 2651 | + hisi_hba->intr_coal_count); |
|---|
| 2652 | + } |
|---|
| 2653 | + phys_init_v3_hw(hisi_hba); |
|---|
| 2654 | +} |
|---|
| 2655 | + |
|---|
| 2656 | +static ssize_t intr_coal_ticks_v3_hw_show(struct device *dev, |
|---|
| 2657 | + struct device_attribute *attr, |
|---|
| 2658 | + char *buf) |
|---|
| 2659 | +{ |
|---|
| 2660 | + struct Scsi_Host *shost = class_to_shost(dev); |
|---|
| 2661 | + struct hisi_hba *hisi_hba = shost_priv(shost); |
|---|
| 2662 | + |
|---|
| 2663 | + return scnprintf(buf, PAGE_SIZE, "%u\n", |
|---|
| 2664 | + hisi_hba->intr_coal_ticks); |
|---|
| 2665 | +} |
|---|
| 2666 | + |
|---|
| 2667 | +static ssize_t intr_coal_ticks_v3_hw_store(struct device *dev, |
|---|
| 2668 | + struct device_attribute *attr, |
|---|
| 2669 | + const char *buf, size_t count) |
|---|
| 2670 | +{ |
|---|
| 2671 | + struct Scsi_Host *shost = class_to_shost(dev); |
|---|
| 2672 | + struct hisi_hba *hisi_hba = shost_priv(shost); |
|---|
| 2673 | + u32 intr_coal_ticks; |
|---|
| 2674 | + int ret; |
|---|
| 2675 | + |
|---|
| 2676 | + ret = kstrtou32(buf, 10, &intr_coal_ticks); |
|---|
| 2677 | + if (ret) { |
|---|
| 2678 | + dev_err(dev, "Input data of interrupt coalesce unmatch\n"); |
|---|
| 2679 | + return -EINVAL; |
|---|
| 2680 | + } |
|---|
| 2681 | + |
|---|
| 2682 | + if (intr_coal_ticks >= BIT(24)) { |
|---|
| 2683 | + dev_err(dev, "intr_coal_ticks must be less than 2^24!\n"); |
|---|
| 2684 | + return -EINVAL; |
|---|
| 2685 | + } |
|---|
| 2686 | + |
|---|
| 2687 | + hisi_hba->intr_coal_ticks = intr_coal_ticks; |
|---|
| 2688 | + |
|---|
| 2689 | + config_intr_coal_v3_hw(hisi_hba); |
|---|
| 2690 | + |
|---|
| 2691 | + return count; |
|---|
| 2692 | +} |
|---|
| 2693 | +static DEVICE_ATTR_RW(intr_coal_ticks_v3_hw); |
|---|
| 2694 | + |
|---|
| 2695 | +static ssize_t intr_coal_count_v3_hw_show(struct device *dev, |
|---|
| 2696 | + struct device_attribute |
|---|
| 2697 | + *attr, char *buf) |
|---|
| 2698 | +{ |
|---|
| 2699 | + struct Scsi_Host *shost = class_to_shost(dev); |
|---|
| 2700 | + struct hisi_hba *hisi_hba = shost_priv(shost); |
|---|
| 2701 | + |
|---|
| 2702 | + return scnprintf(buf, PAGE_SIZE, "%u\n", |
|---|
| 2703 | + hisi_hba->intr_coal_count); |
|---|
| 2704 | +} |
|---|
| 2705 | + |
|---|
| 2706 | +static ssize_t intr_coal_count_v3_hw_store(struct device *dev, |
|---|
| 2707 | + struct device_attribute |
|---|
| 2708 | + *attr, const char *buf, size_t count) |
|---|
| 2709 | +{ |
|---|
| 2710 | + struct Scsi_Host *shost = class_to_shost(dev); |
|---|
| 2711 | + struct hisi_hba *hisi_hba = shost_priv(shost); |
|---|
| 2712 | + u32 intr_coal_count; |
|---|
| 2713 | + int ret; |
|---|
| 2714 | + |
|---|
| 2715 | + ret = kstrtou32(buf, 10, &intr_coal_count); |
|---|
| 2716 | + if (ret) { |
|---|
| 2717 | + dev_err(dev, "Input data of interrupt coalesce unmatch\n"); |
|---|
| 2718 | + return -EINVAL; |
|---|
| 2719 | + } |
|---|
| 2720 | + |
|---|
| 2721 | + if (intr_coal_count >= BIT(8)) { |
|---|
| 2722 | + dev_err(dev, "intr_coal_count must be less than 2^8!\n"); |
|---|
| 2723 | + return -EINVAL; |
|---|
| 2724 | + } |
|---|
| 2725 | + |
|---|
| 2726 | + hisi_hba->intr_coal_count = intr_coal_count; |
|---|
| 2727 | + |
|---|
| 2728 | + config_intr_coal_v3_hw(hisi_hba); |
|---|
| 2729 | + |
|---|
| 2730 | + return count; |
|---|
| 2731 | +} |
|---|
| 2732 | +static DEVICE_ATTR_RW(intr_coal_count_v3_hw); |
|---|
| 2733 | + |
|---|
| 2734 | +static int slave_configure_v3_hw(struct scsi_device *sdev) |
|---|
| 2735 | +{ |
|---|
| 2736 | + struct Scsi_Host *shost = dev_to_shost(&sdev->sdev_gendev); |
|---|
| 2737 | + struct domain_device *ddev = sdev_to_domain_dev(sdev); |
|---|
| 2738 | + struct hisi_hba *hisi_hba = shost_priv(shost); |
|---|
| 2739 | + struct device *dev = hisi_hba->dev; |
|---|
| 2740 | + int ret = sas_slave_configure(sdev); |
|---|
| 2741 | + |
|---|
| 2742 | + if (ret) |
|---|
| 2743 | + return ret; |
|---|
| 2744 | + if (!dev_is_sata(ddev)) |
|---|
| 2745 | + sas_change_queue_depth(sdev, 64); |
|---|
| 2746 | + |
|---|
| 2747 | + if (sdev->type == TYPE_ENCLOSURE) |
|---|
| 2748 | + return 0; |
|---|
| 2749 | + |
|---|
| 2750 | + if (!device_link_add(&sdev->sdev_gendev, dev, |
|---|
| 2751 | + DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE)) { |
|---|
| 2752 | + if (pm_runtime_enabled(dev)) { |
|---|
| 2753 | + dev_info(dev, "add device link failed, disable runtime PM for the host\n"); |
|---|
| 2754 | + pm_runtime_disable(dev); |
|---|
| 2755 | + } |
|---|
| 2756 | + } |
|---|
| 2757 | + |
|---|
| 2758 | + return 0; |
|---|
| 2759 | +} |
|---|
| 2760 | + |
|---|
| 2761 | +static struct device_attribute *host_attrs_v3_hw[] = { |
|---|
| 2762 | + &dev_attr_phy_event_threshold, |
|---|
| 2763 | + &dev_attr_intr_conv_v3_hw, |
|---|
| 2764 | + &dev_attr_intr_coal_ticks_v3_hw, |
|---|
| 2765 | + &dev_attr_intr_coal_count_v3_hw, |
|---|
| 2766 | + NULL |
|---|
| 2767 | +}; |
|---|
| 2768 | + |
|---|
| 2769 | +static const struct hisi_sas_debugfs_reg_lu debugfs_port_reg_lu[] = { |
|---|
| 2770 | + HISI_SAS_DEBUGFS_REG(PHY_CFG), |
|---|
| 2771 | + HISI_SAS_DEBUGFS_REG(HARD_PHY_LINKRATE), |
|---|
| 2772 | + HISI_SAS_DEBUGFS_REG(PROG_PHY_LINK_RATE), |
|---|
| 2773 | + HISI_SAS_DEBUGFS_REG(PHY_CTRL), |
|---|
| 2774 | + HISI_SAS_DEBUGFS_REG(SL_CFG), |
|---|
| 2775 | + HISI_SAS_DEBUGFS_REG(AIP_LIMIT), |
|---|
| 2776 | + HISI_SAS_DEBUGFS_REG(SL_CONTROL), |
|---|
| 2777 | + HISI_SAS_DEBUGFS_REG(RX_PRIMS_STATUS), |
|---|
| 2778 | + HISI_SAS_DEBUGFS_REG(TX_ID_DWORD0), |
|---|
| 2779 | + HISI_SAS_DEBUGFS_REG(TX_ID_DWORD1), |
|---|
| 2780 | + HISI_SAS_DEBUGFS_REG(TX_ID_DWORD2), |
|---|
| 2781 | + HISI_SAS_DEBUGFS_REG(TX_ID_DWORD3), |
|---|
| 2782 | + HISI_SAS_DEBUGFS_REG(TX_ID_DWORD4), |
|---|
| 2783 | + HISI_SAS_DEBUGFS_REG(TX_ID_DWORD5), |
|---|
| 2784 | + HISI_SAS_DEBUGFS_REG(TX_ID_DWORD6), |
|---|
| 2785 | + HISI_SAS_DEBUGFS_REG(TXID_AUTO), |
|---|
| 2786 | + HISI_SAS_DEBUGFS_REG(RX_IDAF_DWORD0), |
|---|
| 2787 | + HISI_SAS_DEBUGFS_REG(RXOP_CHECK_CFG_H), |
|---|
| 2788 | + HISI_SAS_DEBUGFS_REG(STP_LINK_TIMER), |
|---|
| 2789 | + HISI_SAS_DEBUGFS_REG(STP_LINK_TIMEOUT_STATE), |
|---|
| 2790 | + HISI_SAS_DEBUGFS_REG(CON_CFG_DRIVER), |
|---|
| 2791 | + HISI_SAS_DEBUGFS_REG(SAS_SSP_CON_TIMER_CFG), |
|---|
| 2792 | + HISI_SAS_DEBUGFS_REG(SAS_SMP_CON_TIMER_CFG), |
|---|
| 2793 | + HISI_SAS_DEBUGFS_REG(SAS_STP_CON_TIMER_CFG), |
|---|
| 2794 | + HISI_SAS_DEBUGFS_REG(CHL_INT0), |
|---|
| 2795 | + HISI_SAS_DEBUGFS_REG(CHL_INT1), |
|---|
| 2796 | + HISI_SAS_DEBUGFS_REG(CHL_INT2), |
|---|
| 2797 | + HISI_SAS_DEBUGFS_REG(CHL_INT0_MSK), |
|---|
| 2798 | + HISI_SAS_DEBUGFS_REG(CHL_INT1_MSK), |
|---|
| 2799 | + HISI_SAS_DEBUGFS_REG(CHL_INT2_MSK), |
|---|
| 2800 | + HISI_SAS_DEBUGFS_REG(SAS_EC_INT_COAL_TIME), |
|---|
| 2801 | + HISI_SAS_DEBUGFS_REG(CHL_INT_COAL_EN), |
|---|
| 2802 | + HISI_SAS_DEBUGFS_REG(SAS_RX_TRAIN_TIMER), |
|---|
| 2803 | + HISI_SAS_DEBUGFS_REG(PHY_CTRL_RDY_MSK), |
|---|
| 2804 | + HISI_SAS_DEBUGFS_REG(PHYCTRL_NOT_RDY_MSK), |
|---|
| 2805 | + HISI_SAS_DEBUGFS_REG(PHYCTRL_DWS_RESET_MSK), |
|---|
| 2806 | + HISI_SAS_DEBUGFS_REG(PHYCTRL_PHY_ENA_MSK), |
|---|
| 2807 | + HISI_SAS_DEBUGFS_REG(SL_RX_BCAST_CHK_MSK), |
|---|
| 2808 | + HISI_SAS_DEBUGFS_REG(PHYCTRL_OOB_RESTART_MSK), |
|---|
| 2809 | + HISI_SAS_DEBUGFS_REG(DMA_TX_STATUS), |
|---|
| 2810 | + HISI_SAS_DEBUGFS_REG(DMA_RX_STATUS), |
|---|
| 2811 | + HISI_SAS_DEBUGFS_REG(COARSETUNE_TIME), |
|---|
| 2812 | + HISI_SAS_DEBUGFS_REG(ERR_CNT_DWS_LOST), |
|---|
| 2813 | + HISI_SAS_DEBUGFS_REG(ERR_CNT_RESET_PROB), |
|---|
| 2814 | + HISI_SAS_DEBUGFS_REG(ERR_CNT_INVLD_DW), |
|---|
| 2815 | + HISI_SAS_DEBUGFS_REG(ERR_CNT_CODE_ERR), |
|---|
| 2816 | + HISI_SAS_DEBUGFS_REG(ERR_CNT_DISP_ERR), |
|---|
| 2817 | + {} |
|---|
| 2818 | +}; |
|---|
| 2819 | + |
|---|
| 2820 | +static const struct hisi_sas_debugfs_reg debugfs_port_reg = { |
|---|
| 2821 | + .lu = debugfs_port_reg_lu, |
|---|
| 2822 | + .count = 0x100, |
|---|
| 2823 | + .base_off = PORT_BASE, |
|---|
| 2824 | + .read_port_reg = hisi_sas_phy_read32, |
|---|
| 2825 | +}; |
|---|
| 2826 | + |
|---|
| 2827 | +static const struct hisi_sas_debugfs_reg_lu debugfs_global_reg_lu[] = { |
|---|
| 2828 | + HISI_SAS_DEBUGFS_REG(DLVRY_QUEUE_ENABLE), |
|---|
| 2829 | + HISI_SAS_DEBUGFS_REG(PHY_CONTEXT), |
|---|
| 2830 | + HISI_SAS_DEBUGFS_REG(PHY_STATE), |
|---|
| 2831 | + HISI_SAS_DEBUGFS_REG(PHY_PORT_NUM_MA), |
|---|
| 2832 | + HISI_SAS_DEBUGFS_REG(PHY_CONN_RATE), |
|---|
| 2833 | + HISI_SAS_DEBUGFS_REG(ITCT_CLR), |
|---|
| 2834 | + HISI_SAS_DEBUGFS_REG(IO_SATA_BROKEN_MSG_ADDR_LO), |
|---|
| 2835 | + HISI_SAS_DEBUGFS_REG(IO_SATA_BROKEN_MSG_ADDR_HI), |
|---|
| 2836 | + HISI_SAS_DEBUGFS_REG(SATA_INITI_D2H_STORE_ADDR_LO), |
|---|
| 2837 | + HISI_SAS_DEBUGFS_REG(SATA_INITI_D2H_STORE_ADDR_HI), |
|---|
| 2838 | + HISI_SAS_DEBUGFS_REG(CFG_MAX_TAG), |
|---|
| 2839 | + HISI_SAS_DEBUGFS_REG(HGC_SAS_TX_OPEN_FAIL_RETRY_CTRL), |
|---|
| 2840 | + HISI_SAS_DEBUGFS_REG(HGC_SAS_TXFAIL_RETRY_CTRL), |
|---|
| 2841 | + HISI_SAS_DEBUGFS_REG(HGC_GET_ITV_TIME), |
|---|
| 2842 | + HISI_SAS_DEBUGFS_REG(DEVICE_MSG_WORK_MODE), |
|---|
| 2843 | + HISI_SAS_DEBUGFS_REG(OPENA_WT_CONTI_TIME), |
|---|
| 2844 | + HISI_SAS_DEBUGFS_REG(I_T_NEXUS_LOSS_TIME), |
|---|
| 2845 | + HISI_SAS_DEBUGFS_REG(MAX_CON_TIME_LIMIT_TIME), |
|---|
| 2846 | + HISI_SAS_DEBUGFS_REG(BUS_INACTIVE_LIMIT_TIME), |
|---|
| 2847 | + HISI_SAS_DEBUGFS_REG(REJECT_TO_OPEN_LIMIT_TIME), |
|---|
| 2848 | + HISI_SAS_DEBUGFS_REG(CQ_INT_CONVERGE_EN), |
|---|
| 2849 | + HISI_SAS_DEBUGFS_REG(CFG_AGING_TIME), |
|---|
| 2850 | + HISI_SAS_DEBUGFS_REG(HGC_DFX_CFG2), |
|---|
| 2851 | + HISI_SAS_DEBUGFS_REG(CFG_ABT_SET_QUERY_IPTT), |
|---|
| 2852 | + HISI_SAS_DEBUGFS_REG(CFG_ABT_SET_IPTT_DONE), |
|---|
| 2853 | + HISI_SAS_DEBUGFS_REG(HGC_IOMB_PROC1_STATUS), |
|---|
| 2854 | + HISI_SAS_DEBUGFS_REG(CHNL_INT_STATUS), |
|---|
| 2855 | + HISI_SAS_DEBUGFS_REG(HGC_AXI_FIFO_ERR_INFO), |
|---|
| 2856 | + HISI_SAS_DEBUGFS_REG(INT_COAL_EN), |
|---|
| 2857 | + HISI_SAS_DEBUGFS_REG(OQ_INT_COAL_TIME), |
|---|
| 2858 | + HISI_SAS_DEBUGFS_REG(OQ_INT_COAL_CNT), |
|---|
| 2859 | + HISI_SAS_DEBUGFS_REG(ENT_INT_COAL_TIME), |
|---|
| 2860 | + HISI_SAS_DEBUGFS_REG(ENT_INT_COAL_CNT), |
|---|
| 2861 | + HISI_SAS_DEBUGFS_REG(OQ_INT_SRC), |
|---|
| 2862 | + HISI_SAS_DEBUGFS_REG(OQ_INT_SRC_MSK), |
|---|
| 2863 | + HISI_SAS_DEBUGFS_REG(ENT_INT_SRC1), |
|---|
| 2864 | + HISI_SAS_DEBUGFS_REG(ENT_INT_SRC2), |
|---|
| 2865 | + HISI_SAS_DEBUGFS_REG(ENT_INT_SRC3), |
|---|
| 2866 | + HISI_SAS_DEBUGFS_REG(ENT_INT_SRC_MSK1), |
|---|
| 2867 | + HISI_SAS_DEBUGFS_REG(ENT_INT_SRC_MSK2), |
|---|
| 2868 | + HISI_SAS_DEBUGFS_REG(ENT_INT_SRC_MSK3), |
|---|
| 2869 | + HISI_SAS_DEBUGFS_REG(CHNL_PHYUPDOWN_INT_MSK), |
|---|
| 2870 | + HISI_SAS_DEBUGFS_REG(CHNL_ENT_INT_MSK), |
|---|
| 2871 | + HISI_SAS_DEBUGFS_REG(HGC_COM_INT_MSK), |
|---|
| 2872 | + HISI_SAS_DEBUGFS_REG(SAS_ECC_INTR), |
|---|
| 2873 | + HISI_SAS_DEBUGFS_REG(SAS_ECC_INTR_MSK), |
|---|
| 2874 | + HISI_SAS_DEBUGFS_REG(HGC_ERR_STAT_EN), |
|---|
| 2875 | + HISI_SAS_DEBUGFS_REG(CQE_SEND_CNT), |
|---|
| 2876 | + HISI_SAS_DEBUGFS_REG(DLVRY_Q_0_DEPTH), |
|---|
| 2877 | + HISI_SAS_DEBUGFS_REG(DLVRY_Q_0_WR_PTR), |
|---|
| 2878 | + HISI_SAS_DEBUGFS_REG(DLVRY_Q_0_RD_PTR), |
|---|
| 2879 | + HISI_SAS_DEBUGFS_REG(HYPER_STREAM_ID_EN_CFG), |
|---|
| 2880 | + HISI_SAS_DEBUGFS_REG(OQ0_INT_SRC_MSK), |
|---|
| 2881 | + HISI_SAS_DEBUGFS_REG(COMPL_Q_0_DEPTH), |
|---|
| 2882 | + HISI_SAS_DEBUGFS_REG(COMPL_Q_0_WR_PTR), |
|---|
| 2883 | + HISI_SAS_DEBUGFS_REG(COMPL_Q_0_RD_PTR), |
|---|
| 2884 | + HISI_SAS_DEBUGFS_REG(AWQOS_AWCACHE_CFG), |
|---|
| 2885 | + HISI_SAS_DEBUGFS_REG(ARQOS_ARCACHE_CFG), |
|---|
| 2886 | + HISI_SAS_DEBUGFS_REG(HILINK_ERR_DFX), |
|---|
| 2887 | + HISI_SAS_DEBUGFS_REG(SAS_GPIO_CFG_0), |
|---|
| 2888 | + HISI_SAS_DEBUGFS_REG(SAS_GPIO_CFG_1), |
|---|
| 2889 | + HISI_SAS_DEBUGFS_REG(SAS_GPIO_TX_0_1), |
|---|
| 2890 | + HISI_SAS_DEBUGFS_REG(SAS_CFG_DRIVE_VLD), |
|---|
| 2891 | + {} |
|---|
| 2892 | +}; |
|---|
| 2893 | + |
|---|
| 2894 | +static const struct hisi_sas_debugfs_reg debugfs_global_reg = { |
|---|
| 2895 | + .lu = debugfs_global_reg_lu, |
|---|
| 2896 | + .count = 0x800, |
|---|
| 2897 | + .read_global_reg = hisi_sas_read32, |
|---|
| 2898 | +}; |
|---|
| 2899 | + |
|---|
| 2900 | +static const struct hisi_sas_debugfs_reg_lu debugfs_axi_reg_lu[] = { |
|---|
| 2901 | + HISI_SAS_DEBUGFS_REG(AM_CFG_MAX_TRANS), |
|---|
| 2902 | + HISI_SAS_DEBUGFS_REG(AM_CFG_SINGLE_PORT_MAX_TRANS), |
|---|
| 2903 | + HISI_SAS_DEBUGFS_REG(AXI_CFG), |
|---|
| 2904 | + HISI_SAS_DEBUGFS_REG(AM_ROB_ECC_ERR_ADDR), |
|---|
| 2905 | + {} |
|---|
| 2906 | +}; |
|---|
| 2907 | + |
|---|
| 2908 | +static const struct hisi_sas_debugfs_reg debugfs_axi_reg = { |
|---|
| 2909 | + .lu = debugfs_axi_reg_lu, |
|---|
| 2910 | + .count = 0x61, |
|---|
| 2911 | + .base_off = AXI_MASTER_CFG_BASE, |
|---|
| 2912 | + .read_global_reg = hisi_sas_read32, |
|---|
| 2913 | +}; |
|---|
| 2914 | + |
|---|
| 2915 | +static const struct hisi_sas_debugfs_reg_lu debugfs_ras_reg_lu[] = { |
|---|
| 2916 | + HISI_SAS_DEBUGFS_REG(SAS_RAS_INTR0), |
|---|
| 2917 | + HISI_SAS_DEBUGFS_REG(SAS_RAS_INTR1), |
|---|
| 2918 | + HISI_SAS_DEBUGFS_REG(SAS_RAS_INTR0_MASK), |
|---|
| 2919 | + HISI_SAS_DEBUGFS_REG(SAS_RAS_INTR1_MASK), |
|---|
| 2920 | + HISI_SAS_DEBUGFS_REG(CFG_SAS_RAS_INTR_MASK), |
|---|
| 2921 | + HISI_SAS_DEBUGFS_REG(SAS_RAS_INTR2), |
|---|
| 2922 | + HISI_SAS_DEBUGFS_REG(SAS_RAS_INTR2_MASK), |
|---|
| 2923 | + {} |
|---|
| 2924 | +}; |
|---|
| 2925 | + |
|---|
| 2926 | +static const struct hisi_sas_debugfs_reg debugfs_ras_reg = { |
|---|
| 2927 | + .lu = debugfs_ras_reg_lu, |
|---|
| 2928 | + .count = 0x10, |
|---|
| 2929 | + .base_off = RAS_BASE, |
|---|
| 2930 | + .read_global_reg = hisi_sas_read32, |
|---|
| 2931 | +}; |
|---|
| 2932 | + |
|---|
| 2933 | +static void debugfs_snapshot_prepare_v3_hw(struct hisi_hba *hisi_hba) |
|---|
| 2934 | +{ |
|---|
| 2935 | + set_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); |
|---|
| 2936 | + |
|---|
| 2937 | + hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, 0); |
|---|
| 2938 | + |
|---|
| 2939 | + wait_cmds_complete_timeout_v3_hw(hisi_hba, 100, 5000); |
|---|
| 2940 | + |
|---|
| 2941 | + hisi_sas_sync_irqs(hisi_hba); |
|---|
| 2942 | +} |
|---|
| 2943 | + |
|---|
| 2944 | +static void debugfs_snapshot_restore_v3_hw(struct hisi_hba *hisi_hba) |
|---|
| 2945 | +{ |
|---|
| 2946 | + hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, |
|---|
| 2947 | + (u32)((1ULL << hisi_hba->queue_count) - 1)); |
|---|
| 2948 | + |
|---|
| 2949 | + clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); |
|---|
| 2950 | +} |
|---|
| 2951 | + |
|---|
| 2952 | +static void read_iost_itct_cache_v3_hw(struct hisi_hba *hisi_hba, |
|---|
| 2953 | + enum hisi_sas_debugfs_cache_type type, |
|---|
| 2954 | + u32 *cache) |
|---|
| 2955 | +{ |
|---|
| 2956 | + u32 cache_dw_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * |
|---|
| 2957 | + HISI_SAS_IOST_ITCT_CACHE_NUM; |
|---|
| 2958 | + struct device *dev = hisi_hba->dev; |
|---|
| 2959 | + u32 *buf = cache; |
|---|
| 2960 | + u32 i, val; |
|---|
| 2961 | + |
|---|
| 2962 | + hisi_sas_write32(hisi_hba, TAB_RD_TYPE, type); |
|---|
| 2963 | + |
|---|
| 2964 | + for (i = 0; i < HISI_SAS_IOST_ITCT_CACHE_DW_SZ; i++) { |
|---|
| 2965 | + val = hisi_sas_read32(hisi_hba, TAB_DFX); |
|---|
| 2966 | + if (val == 0xffffffff) |
|---|
| 2967 | + break; |
|---|
| 2968 | + } |
|---|
| 2969 | + |
|---|
| 2970 | + if (val != 0xffffffff) { |
|---|
| 2971 | + dev_err(dev, "Issue occurred in reading IOST/ITCT cache!\n"); |
|---|
| 2972 | + return; |
|---|
| 2973 | + } |
|---|
| 2974 | + |
|---|
| 2975 | + memset(buf, 0, cache_dw_size * 4); |
|---|
| 2976 | + buf[0] = val; |
|---|
| 2977 | + |
|---|
| 2978 | + for (i = 1; i < cache_dw_size; i++) |
|---|
| 2979 | + buf[i] = hisi_sas_read32(hisi_hba, TAB_DFX); |
|---|
| 2980 | +} |
|---|
| 2981 | + |
|---|
| 2982 | +static void hisi_sas_bist_test_prep_v3_hw(struct hisi_hba *hisi_hba) |
|---|
| 2983 | +{ |
|---|
| 2984 | + u32 reg_val; |
|---|
| 2985 | + int phy_no = hisi_hba->debugfs_bist_phy_no; |
|---|
| 2986 | + int i; |
|---|
| 2987 | + |
|---|
| 2988 | + /* disable PHY */ |
|---|
| 2989 | + hisi_sas_phy_enable(hisi_hba, phy_no, 0); |
|---|
| 2990 | + |
|---|
| 2991 | + /* update FFE */ |
|---|
| 2992 | + for (i = 0; i < FFE_CFG_MAX; i++) |
|---|
| 2993 | + hisi_sas_phy_write32(hisi_hba, phy_no, TXDEEMPH_G1 + (i * 0x4), |
|---|
| 2994 | + hisi_hba->debugfs_bist_ffe[phy_no][i]); |
|---|
| 2995 | + |
|---|
| 2996 | + /* disable ALOS */ |
|---|
| 2997 | + reg_val = hisi_sas_phy_read32(hisi_hba, phy_no, SERDES_CFG); |
|---|
| 2998 | + reg_val |= CFG_ALOS_CHK_DISABLE_MSK; |
|---|
| 2999 | + hisi_sas_phy_write32(hisi_hba, phy_no, SERDES_CFG, reg_val); |
|---|
| 3000 | +} |
|---|
| 3001 | + |
|---|
| 3002 | +static void hisi_sas_bist_test_restore_v3_hw(struct hisi_hba *hisi_hba) |
|---|
| 3003 | +{ |
|---|
| 3004 | + u32 reg_val; |
|---|
| 3005 | + int phy_no = hisi_hba->debugfs_bist_phy_no; |
|---|
| 3006 | + |
|---|
| 3007 | + /* disable loopback */ |
|---|
| 3008 | + reg_val = hisi_sas_phy_read32(hisi_hba, phy_no, SAS_PHY_BIST_CTRL); |
|---|
| 3009 | + reg_val &= ~(CFG_RX_BIST_EN_MSK | CFG_TX_BIST_EN_MSK | |
|---|
| 3010 | + CFG_BIST_TEST_MSK); |
|---|
| 3011 | + hisi_sas_phy_write32(hisi_hba, phy_no, SAS_PHY_BIST_CTRL, reg_val); |
|---|
| 3012 | + |
|---|
| 3013 | + /* enable ALOS */ |
|---|
| 3014 | + reg_val = hisi_sas_phy_read32(hisi_hba, phy_no, SERDES_CFG); |
|---|
| 3015 | + reg_val &= ~CFG_ALOS_CHK_DISABLE_MSK; |
|---|
| 3016 | + hisi_sas_phy_write32(hisi_hba, phy_no, SERDES_CFG, reg_val); |
|---|
| 3017 | + |
|---|
| 3018 | + /* restore the linkrate */ |
|---|
| 3019 | + reg_val = hisi_sas_phy_read32(hisi_hba, phy_no, PROG_PHY_LINK_RATE); |
|---|
| 3020 | + /* init OOB link rate as 1.5 Gbits */ |
|---|
| 3021 | + reg_val &= ~CFG_PROG_OOB_PHY_LINK_RATE_MSK; |
|---|
| 3022 | + reg_val |= (0x8 << CFG_PROG_OOB_PHY_LINK_RATE_OFF); |
|---|
| 3023 | + hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE, reg_val); |
|---|
| 3024 | + |
|---|
| 3025 | + /* enable PHY */ |
|---|
| 3026 | + hisi_sas_phy_enable(hisi_hba, phy_no, 1); |
|---|
| 3027 | +} |
|---|
| 3028 | + |
|---|
| 3029 | +#define SAS_PHY_BIST_CODE_INIT 0x1 |
|---|
| 3030 | +#define SAS_PHY_BIST_CODE1_INIT 0X80 |
|---|
| 3031 | +static int debugfs_set_bist_v3_hw(struct hisi_hba *hisi_hba, bool enable) |
|---|
| 3032 | +{ |
|---|
| 3033 | + u32 reg_val, mode_tmp; |
|---|
| 3034 | + u32 linkrate = hisi_hba->debugfs_bist_linkrate; |
|---|
| 3035 | + u32 phy_no = hisi_hba->debugfs_bist_phy_no; |
|---|
| 3036 | + u32 *ffe = hisi_hba->debugfs_bist_ffe[phy_no]; |
|---|
| 3037 | + u32 code_mode = hisi_hba->debugfs_bist_code_mode; |
|---|
| 3038 | + u32 path_mode = hisi_hba->debugfs_bist_mode; |
|---|
| 3039 | + u32 *fix_code = &hisi_hba->debugfs_bist_fixed_code[0]; |
|---|
| 3040 | + struct device *dev = hisi_hba->dev; |
|---|
| 3041 | + |
|---|
| 3042 | + dev_info(dev, "BIST info:phy%d link_rate=%d code_mode=%d path_mode=%d ffe={0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x} fixed_code={0x%x, 0x%x}\n", |
|---|
| 3043 | + phy_no, linkrate, code_mode, path_mode, |
|---|
| 3044 | + ffe[FFE_SAS_1_5_GBPS], ffe[FFE_SAS_3_0_GBPS], |
|---|
| 3045 | + ffe[FFE_SAS_6_0_GBPS], ffe[FFE_SAS_12_0_GBPS], |
|---|
| 3046 | + ffe[FFE_SATA_1_5_GBPS], ffe[FFE_SATA_3_0_GBPS], |
|---|
| 3047 | + ffe[FFE_SATA_6_0_GBPS], fix_code[FIXED_CODE], |
|---|
| 3048 | + fix_code[FIXED_CODE_1]); |
|---|
| 3049 | + mode_tmp = path_mode ? 2 : 1; |
|---|
| 3050 | + if (enable) { |
|---|
| 3051 | + /* some preparations before bist test */ |
|---|
| 3052 | + hisi_sas_bist_test_prep_v3_hw(hisi_hba); |
|---|
| 3053 | + |
|---|
| 3054 | + /* set linkrate of bit test*/ |
|---|
| 3055 | + reg_val = hisi_sas_phy_read32(hisi_hba, phy_no, |
|---|
| 3056 | + PROG_PHY_LINK_RATE); |
|---|
| 3057 | + reg_val &= ~CFG_PROG_OOB_PHY_LINK_RATE_MSK; |
|---|
| 3058 | + reg_val |= (linkrate << CFG_PROG_OOB_PHY_LINK_RATE_OFF); |
|---|
| 3059 | + hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE, |
|---|
| 3060 | + reg_val); |
|---|
| 3061 | + |
|---|
| 3062 | + /* set code mode of bit test */ |
|---|
| 3063 | + reg_val = hisi_sas_phy_read32(hisi_hba, phy_no, |
|---|
| 3064 | + SAS_PHY_BIST_CTRL); |
|---|
| 3065 | + reg_val &= ~(CFG_BIST_MODE_SEL_MSK | CFG_LOOP_TEST_MODE_MSK | |
|---|
| 3066 | + CFG_RX_BIST_EN_MSK | CFG_TX_BIST_EN_MSK | |
|---|
| 3067 | + CFG_BIST_TEST_MSK); |
|---|
| 3068 | + reg_val |= ((code_mode << CFG_BIST_MODE_SEL_OFF) | |
|---|
| 3069 | + (mode_tmp << CFG_LOOP_TEST_MODE_OFF) | |
|---|
| 3070 | + CFG_BIST_TEST_MSK); |
|---|
| 3071 | + hisi_sas_phy_write32(hisi_hba, phy_no, SAS_PHY_BIST_CTRL, |
|---|
| 3072 | + reg_val); |
|---|
| 3073 | + |
|---|
| 3074 | + /* set the bist init value */ |
|---|
| 3075 | + if (code_mode == HISI_SAS_BIST_CODE_MODE_FIXED_DATA) { |
|---|
| 3076 | + reg_val = hisi_hba->debugfs_bist_fixed_code[0]; |
|---|
| 3077 | + hisi_sas_phy_write32(hisi_hba, phy_no, |
|---|
| 3078 | + SAS_PHY_BIST_CODE, reg_val); |
|---|
| 3079 | + |
|---|
| 3080 | + reg_val = hisi_hba->debugfs_bist_fixed_code[1]; |
|---|
| 3081 | + hisi_sas_phy_write32(hisi_hba, phy_no, |
|---|
| 3082 | + SAS_PHY_BIST_CODE1, reg_val); |
|---|
| 3083 | + } else { |
|---|
| 3084 | + hisi_sas_phy_write32(hisi_hba, phy_no, |
|---|
| 3085 | + SAS_PHY_BIST_CODE, |
|---|
| 3086 | + SAS_PHY_BIST_CODE_INIT); |
|---|
| 3087 | + hisi_sas_phy_write32(hisi_hba, phy_no, |
|---|
| 3088 | + SAS_PHY_BIST_CODE1, |
|---|
| 3089 | + SAS_PHY_BIST_CODE1_INIT); |
|---|
| 3090 | + } |
|---|
| 3091 | + |
|---|
| 3092 | + mdelay(100); |
|---|
| 3093 | + reg_val |= (CFG_RX_BIST_EN_MSK | CFG_TX_BIST_EN_MSK); |
|---|
| 3094 | + hisi_sas_phy_write32(hisi_hba, phy_no, SAS_PHY_BIST_CTRL, |
|---|
| 3095 | + reg_val); |
|---|
| 3096 | + |
|---|
| 3097 | + /* clear error bit */ |
|---|
| 3098 | + mdelay(100); |
|---|
| 3099 | + hisi_sas_phy_read32(hisi_hba, phy_no, SAS_BIST_ERR_CNT); |
|---|
| 3100 | + } else { |
|---|
| 3101 | + /* disable bist test and recover it */ |
|---|
| 3102 | + hisi_hba->debugfs_bist_cnt += hisi_sas_phy_read32(hisi_hba, |
|---|
| 3103 | + phy_no, SAS_BIST_ERR_CNT); |
|---|
| 3104 | + hisi_sas_bist_test_restore_v3_hw(hisi_hba); |
|---|
| 3105 | + } |
|---|
| 3106 | + |
|---|
| 3107 | + return 0; |
|---|
| 3108 | +} |
|---|
| 3109 | + |
|---|
| 3110 | +static int hisi_sas_map_queues(struct Scsi_Host *shost) |
|---|
| 3111 | +{ |
|---|
| 3112 | + struct hisi_hba *hisi_hba = shost_priv(shost); |
|---|
| 3113 | + struct blk_mq_queue_map *qmap = &shost->tag_set.map[HCTX_TYPE_DEFAULT]; |
|---|
| 3114 | + |
|---|
| 3115 | + return blk_mq_pci_map_queues(qmap, hisi_hba->pci_dev, |
|---|
| 3116 | + BASE_VECTORS_V3_HW); |
|---|
| 2099 | 3117 | } |
|---|
| 2100 | 3118 | |
|---|
| 2101 | 3119 | static struct scsi_host_template sht_v3_hw = { |
|---|
| 2102 | 3120 | .name = DRV_NAME, |
|---|
| 3121 | + .proc_name = DRV_NAME, |
|---|
| 2103 | 3122 | .module = THIS_MODULE, |
|---|
| 2104 | 3123 | .queuecommand = sas_queuecommand, |
|---|
| 3124 | + .dma_need_drain = ata_scsi_dma_need_drain, |
|---|
| 2105 | 3125 | .target_alloc = sas_target_alloc, |
|---|
| 2106 | | - .slave_configure = hisi_sas_slave_configure, |
|---|
| 3126 | + .slave_configure = slave_configure_v3_hw, |
|---|
| 2107 | 3127 | .scan_finished = hisi_sas_scan_finished, |
|---|
| 2108 | 3128 | .scan_start = hisi_sas_scan_start, |
|---|
| 3129 | + .map_queues = hisi_sas_map_queues, |
|---|
| 2109 | 3130 | .change_queue_depth = sas_change_queue_depth, |
|---|
| 2110 | 3131 | .bios_param = sas_bios_param, |
|---|
| 2111 | | - .can_queue = 1, |
|---|
| 2112 | 3132 | .this_id = -1, |
|---|
| 2113 | | - .sg_tablesize = SG_ALL, |
|---|
| 3133 | + .sg_tablesize = HISI_SAS_SGE_PAGE_CNT, |
|---|
| 3134 | + .sg_prot_tablesize = HISI_SAS_SGE_PAGE_CNT, |
|---|
| 2114 | 3135 | .max_sectors = SCSI_DEFAULT_MAX_SECTORS, |
|---|
| 2115 | | - .use_clustering = ENABLE_CLUSTERING, |
|---|
| 2116 | 3136 | .eh_device_reset_handler = sas_eh_device_reset_handler, |
|---|
| 2117 | 3137 | .eh_target_reset_handler = sas_eh_target_reset_handler, |
|---|
| 2118 | 3138 | .slave_alloc = sas_slave_alloc, |
|---|
| 2119 | 3139 | .target_destroy = sas_target_destroy, |
|---|
| 2120 | 3140 | .ioctl = sas_ioctl, |
|---|
| 2121 | | - .shost_attrs = host_attrs, |
|---|
| 3141 | +#ifdef CONFIG_COMPAT |
|---|
| 3142 | + .compat_ioctl = sas_ioctl, |
|---|
| 3143 | +#endif |
|---|
| 3144 | + .shost_attrs = host_attrs_v3_hw, |
|---|
| 3145 | + .tag_alloc_policy = BLK_TAG_ALLOC_RR, |
|---|
| 3146 | + .host_reset = hisi_sas_host_reset, |
|---|
| 3147 | + .host_tagset = 1, |
|---|
| 2122 | 3148 | }; |
|---|
| 2123 | 3149 | |
|---|
| 2124 | 3150 | static const struct hisi_sas_hw hisi_sas_v3_hw = { |
|---|
| 2125 | 3151 | .hw_init = hisi_sas_v3_init, |
|---|
| 2126 | 3152 | .setup_itct = setup_itct_v3_hw, |
|---|
| 2127 | | - .max_command_entries = HISI_SAS_COMMAND_ENTRIES_V3_HW, |
|---|
| 2128 | 3153 | .get_wideport_bitmap = get_wideport_bitmap_v3_hw, |
|---|
| 2129 | 3154 | .complete_hdr_size = sizeof(struct hisi_sas_complete_v3_hdr), |
|---|
| 2130 | 3155 | .clear_itct = clear_itct_v3_hw, |
|---|
| .. | .. |
|---|
| 2133 | 3158 | .prep_smp = prep_smp_v3_hw, |
|---|
| 2134 | 3159 | .prep_stp = prep_ata_v3_hw, |
|---|
| 2135 | 3160 | .prep_abort = prep_abort_v3_hw, |
|---|
| 2136 | | - .get_free_slot = get_free_slot_v3_hw, |
|---|
| 2137 | 3161 | .start_delivery = start_delivery_v3_hw, |
|---|
| 2138 | | - .slot_complete = slot_complete_v3_hw, |
|---|
| 2139 | 3162 | .phys_init = phys_init_v3_hw, |
|---|
| 2140 | 3163 | .phy_start = start_phy_v3_hw, |
|---|
| 2141 | 3164 | .phy_disable = disable_phy_v3_hw, |
|---|
| .. | .. |
|---|
| 2148 | 3171 | .get_events = phy_get_events_v3_hw, |
|---|
| 2149 | 3172 | .write_gpio = write_gpio_v3_hw, |
|---|
| 2150 | 3173 | .wait_cmds_complete_timeout = wait_cmds_complete_timeout_v3_hw, |
|---|
| 3174 | + .debugfs_reg_array[DEBUGFS_GLOBAL] = &debugfs_global_reg, |
|---|
| 3175 | + .debugfs_reg_array[DEBUGFS_AXI] = &debugfs_axi_reg, |
|---|
| 3176 | + .debugfs_reg_array[DEBUGFS_RAS] = &debugfs_ras_reg, |
|---|
| 3177 | + .debugfs_reg_port = &debugfs_port_reg, |
|---|
| 3178 | + .snapshot_prepare = debugfs_snapshot_prepare_v3_hw, |
|---|
| 3179 | + .snapshot_restore = debugfs_snapshot_restore_v3_hw, |
|---|
| 3180 | + .read_iost_itct_cache = read_iost_itct_cache_v3_hw, |
|---|
| 3181 | + .set_bist = debugfs_set_bist_v3_hw, |
|---|
| 2151 | 3182 | }; |
|---|
| 2152 | 3183 | |
|---|
| 2153 | 3184 | static struct Scsi_Host * |
|---|
| .. | .. |
|---|
| 2165 | 3196 | hisi_hba = shost_priv(shost); |
|---|
| 2166 | 3197 | |
|---|
| 2167 | 3198 | INIT_WORK(&hisi_hba->rst_work, hisi_sas_rst_work_handler); |
|---|
| 3199 | + INIT_WORK(&hisi_hba->debugfs_work, hisi_sas_debugfs_work_handler); |
|---|
| 2168 | 3200 | hisi_hba->hw = &hisi_sas_v3_hw; |
|---|
| 2169 | 3201 | hisi_hba->pci_dev = pdev; |
|---|
| 2170 | 3202 | hisi_hba->dev = dev; |
|---|
| 2171 | 3203 | hisi_hba->shost = shost; |
|---|
| 2172 | 3204 | SHOST_TO_SAS_HA(shost) = &hisi_hba->sha; |
|---|
| 2173 | 3205 | |
|---|
| 2174 | | - timer_setup(&hisi_hba->timer, NULL, 0); |
|---|
| 3206 | + if (prot_mask & ~HISI_SAS_PROT_MASK) |
|---|
| 3207 | + dev_err(dev, "unsupported protection mask 0x%x, using default (0x0)\n", |
|---|
| 3208 | + prot_mask); |
|---|
| 3209 | + else |
|---|
| 3210 | + hisi_hba->prot_mask = prot_mask; |
|---|
| 2175 | 3211 | |
|---|
| 2176 | 3212 | if (hisi_sas_get_fw_info(hisi_hba) < 0) |
|---|
| 2177 | 3213 | goto err_out; |
|---|
| 2178 | 3214 | |
|---|
| 2179 | | - if (hisi_sas_alloc(hisi_hba, shost)) { |
|---|
| 3215 | + if (hisi_sas_alloc(hisi_hba)) { |
|---|
| 2180 | 3216 | hisi_sas_free(hisi_hba); |
|---|
| 2181 | 3217 | goto err_out; |
|---|
| 2182 | 3218 | } |
|---|
| .. | .. |
|---|
| 2209 | 3245 | if (rc) |
|---|
| 2210 | 3246 | goto err_out_disable_device; |
|---|
| 2211 | 3247 | |
|---|
| 2212 | | - if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) || |
|---|
| 2213 | | - (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)) != 0)) { |
|---|
| 2214 | | - if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) || |
|---|
| 2215 | | - (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)) { |
|---|
| 2216 | | - dev_err(dev, "No usable DMA addressing method\n"); |
|---|
| 2217 | | - rc = -EIO; |
|---|
| 2218 | | - goto err_out_regions; |
|---|
| 2219 | | - } |
|---|
| 3248 | + rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); |
|---|
| 3249 | + if (rc) |
|---|
| 3250 | + rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); |
|---|
| 3251 | + if (rc) { |
|---|
| 3252 | + dev_err(dev, "No usable DMA addressing method\n"); |
|---|
| 3253 | + rc = -ENODEV; |
|---|
| 3254 | + goto err_out_regions; |
|---|
| 2220 | 3255 | } |
|---|
| 2221 | 3256 | |
|---|
| 2222 | 3257 | shost = hisi_sas_shost_alloc_pci(pdev); |
|---|
| .. | .. |
|---|
| 2231 | 3266 | |
|---|
| 2232 | 3267 | hisi_hba->regs = pcim_iomap(pdev, 5, 0); |
|---|
| 2233 | 3268 | if (!hisi_hba->regs) { |
|---|
| 2234 | | - dev_err(dev, "cannot map register.\n"); |
|---|
| 3269 | + dev_err(dev, "cannot map register\n"); |
|---|
| 2235 | 3270 | rc = -ENOMEM; |
|---|
| 2236 | 3271 | goto err_out_ha; |
|---|
| 2237 | 3272 | } |
|---|
| .. | .. |
|---|
| 2255 | 3290 | shost->max_lun = ~0; |
|---|
| 2256 | 3291 | shost->max_channel = 1; |
|---|
| 2257 | 3292 | shost->max_cmd_len = 16; |
|---|
| 2258 | | - shost->sg_tablesize = min_t(u16, SG_ALL, HISI_SAS_SGE_PAGE_CNT); |
|---|
| 2259 | | - shost->can_queue = hisi_hba->hw->max_command_entries; |
|---|
| 2260 | | - shost->cmd_per_lun = hisi_hba->hw->max_command_entries; |
|---|
| 3293 | + shost->can_queue = HISI_SAS_UNRESERVED_IPTT; |
|---|
| 3294 | + shost->cmd_per_lun = HISI_SAS_UNRESERVED_IPTT; |
|---|
| 2261 | 3295 | |
|---|
| 2262 | 3296 | sha->sas_ha_name = DRV_NAME; |
|---|
| 2263 | 3297 | sha->dev = dev; |
|---|
| 2264 | 3298 | sha->lldd_module = THIS_MODULE; |
|---|
| 2265 | 3299 | sha->sas_addr = &hisi_hba->sas_addr[0]; |
|---|
| 2266 | 3300 | sha->num_phys = hisi_hba->n_phy; |
|---|
| 2267 | | - sha->core.shost = hisi_hba->shost; |
|---|
| 2268 | 3301 | |
|---|
| 2269 | 3302 | for (i = 0; i < hisi_hba->n_phy; i++) { |
|---|
| 2270 | 3303 | sha->sas_phy[i] = &hisi_hba->phy[i].sas_phy; |
|---|
| 2271 | 3304 | sha->sas_port[i] = &hisi_hba->port[i].sas_port; |
|---|
| 2272 | 3305 | } |
|---|
| 2273 | 3306 | |
|---|
| 3307 | + if (hisi_hba->prot_mask) { |
|---|
| 3308 | + dev_info(dev, "Registering for DIF/DIX prot_mask=0x%x\n", |
|---|
| 3309 | + prot_mask); |
|---|
| 3310 | + scsi_host_set_prot(hisi_hba->shost, prot_mask); |
|---|
| 3311 | + if (hisi_hba->prot_mask & HISI_SAS_DIX_PROT_MASK) |
|---|
| 3312 | + scsi_host_set_guard(hisi_hba->shost, |
|---|
| 3313 | + SHOST_DIX_GUARD_CRC); |
|---|
| 3314 | + } |
|---|
| 3315 | + |
|---|
| 3316 | + if (hisi_sas_debugfs_enable) |
|---|
| 3317 | + hisi_sas_debugfs_init(hisi_hba); |
|---|
| 3318 | + |
|---|
| 3319 | + rc = interrupt_preinit_v3_hw(hisi_hba); |
|---|
| 3320 | + if (rc) |
|---|
| 3321 | + goto err_out_debugfs; |
|---|
| 3322 | + dev_err(dev, "%d hw queues\n", shost->nr_hw_queues); |
|---|
| 2274 | 3323 | rc = scsi_add_host(shost, dev); |
|---|
| 2275 | 3324 | if (rc) |
|---|
| 2276 | | - goto err_out_ha; |
|---|
| 3325 | + goto err_out_debugfs; |
|---|
| 2277 | 3326 | |
|---|
| 2278 | 3327 | rc = sas_register_ha(sha); |
|---|
| 2279 | 3328 | if (rc) |
|---|
| .. | .. |
|---|
| 2285 | 3334 | |
|---|
| 2286 | 3335 | scsi_scan_host(shost); |
|---|
| 2287 | 3336 | |
|---|
| 3337 | + /* |
|---|
| 3338 | + * For the situation that there are ATA disks connected with SAS |
|---|
| 3339 | + * controller, it additionally creates ata_port which will affect the |
|---|
| 3340 | + * child_count of hisi_hba->dev. Even if suspended all the disks, |
|---|
| 3341 | + * ata_port is still and the child_count of hisi_hba->dev is not 0. |
|---|
| 3342 | + * So use pm_suspend_ignore_children() to ignore the effect to |
|---|
| 3343 | + * hisi_hba->dev. |
|---|
| 3344 | + */ |
|---|
| 3345 | + pm_suspend_ignore_children(dev, true); |
|---|
| 3346 | + pm_runtime_put_noidle(&pdev->dev); |
|---|
| 3347 | + |
|---|
| 2288 | 3348 | return 0; |
|---|
| 2289 | 3349 | |
|---|
| 2290 | 3350 | err_out_register_ha: |
|---|
| 2291 | 3351 | scsi_remove_host(shost); |
|---|
| 3352 | +err_out_debugfs: |
|---|
| 3353 | + hisi_sas_debugfs_exit(hisi_hba); |
|---|
| 2292 | 3354 | err_out_ha: |
|---|
| 3355 | + hisi_sas_free(hisi_hba); |
|---|
| 2293 | 3356 | scsi_host_put(shost); |
|---|
| 2294 | 3357 | err_out_regions: |
|---|
| 2295 | 3358 | pci_release_regions(pdev); |
|---|
| .. | .. |
|---|
| 2304 | 3367 | { |
|---|
| 2305 | 3368 | int i; |
|---|
| 2306 | 3369 | |
|---|
| 2307 | | - free_irq(pci_irq_vector(pdev, 1), hisi_hba); |
|---|
| 2308 | | - free_irq(pci_irq_vector(pdev, 2), hisi_hba); |
|---|
| 2309 | | - free_irq(pci_irq_vector(pdev, 11), hisi_hba); |
|---|
| 2310 | | - for (i = 0; i < hisi_hba->queue_count; i++) { |
|---|
| 3370 | + devm_free_irq(&pdev->dev, pci_irq_vector(pdev, 1), hisi_hba); |
|---|
| 3371 | + devm_free_irq(&pdev->dev, pci_irq_vector(pdev, 2), hisi_hba); |
|---|
| 3372 | + devm_free_irq(&pdev->dev, pci_irq_vector(pdev, 11), hisi_hba); |
|---|
| 3373 | + for (i = 0; i < hisi_hba->cq_nvecs; i++) { |
|---|
| 2311 | 3374 | struct hisi_sas_cq *cq = &hisi_hba->cq[i]; |
|---|
| 3375 | + int nr = hisi_sas_intr_conv ? 16 : 16 + i; |
|---|
| 2312 | 3376 | |
|---|
| 2313 | | - free_irq(pci_irq_vector(pdev, i+16), cq); |
|---|
| 3377 | + devm_free_irq(&pdev->dev, pci_irq_vector(pdev, nr), cq); |
|---|
| 2314 | 3378 | } |
|---|
| 2315 | | - pci_free_irq_vectors(pdev); |
|---|
| 2316 | 3379 | } |
|---|
| 2317 | 3380 | |
|---|
| 2318 | 3381 | static void hisi_sas_v3_remove(struct pci_dev *pdev) |
|---|
| .. | .. |
|---|
| 2322 | 3385 | struct hisi_hba *hisi_hba = sha->lldd_ha; |
|---|
| 2323 | 3386 | struct Scsi_Host *shost = sha->core.shost; |
|---|
| 2324 | 3387 | |
|---|
| 3388 | + pm_runtime_get_noresume(dev); |
|---|
| 2325 | 3389 | if (timer_pending(&hisi_hba->timer)) |
|---|
| 2326 | 3390 | del_timer(&hisi_hba->timer); |
|---|
| 2327 | 3391 | |
|---|
| .. | .. |
|---|
| 2329 | 3393 | sas_remove_host(sha->core.shost); |
|---|
| 2330 | 3394 | |
|---|
| 2331 | 3395 | hisi_sas_v3_destroy_irqs(pdev, hisi_hba); |
|---|
| 2332 | | - hisi_sas_kill_tasklets(hisi_hba); |
|---|
| 2333 | 3396 | pci_release_regions(pdev); |
|---|
| 2334 | 3397 | pci_disable_device(pdev); |
|---|
| 2335 | 3398 | hisi_sas_free(hisi_hba); |
|---|
| 3399 | + hisi_sas_debugfs_exit(hisi_hba); |
|---|
| 2336 | 3400 | scsi_host_put(shost); |
|---|
| 2337 | | -} |
|---|
| 2338 | | - |
|---|
| 2339 | | -static const struct hisi_sas_hw_error sas_ras_intr0_nfe[] = { |
|---|
| 2340 | | - { .irq_msk = BIT(19), .msg = "HILINK_INT" }, |
|---|
| 2341 | | - { .irq_msk = BIT(20), .msg = "HILINK_PLL0_OUT_OF_LOCK" }, |
|---|
| 2342 | | - { .irq_msk = BIT(21), .msg = "HILINK_PLL1_OUT_OF_LOCK" }, |
|---|
| 2343 | | - { .irq_msk = BIT(22), .msg = "HILINK_LOSS_OF_REFCLK0" }, |
|---|
| 2344 | | - { .irq_msk = BIT(23), .msg = "HILINK_LOSS_OF_REFCLK1" }, |
|---|
| 2345 | | - { .irq_msk = BIT(24), .msg = "DMAC0_TX_POISON" }, |
|---|
| 2346 | | - { .irq_msk = BIT(25), .msg = "DMAC1_TX_POISON" }, |
|---|
| 2347 | | - { .irq_msk = BIT(26), .msg = "DMAC2_TX_POISON" }, |
|---|
| 2348 | | - { .irq_msk = BIT(27), .msg = "DMAC3_TX_POISON" }, |
|---|
| 2349 | | - { .irq_msk = BIT(28), .msg = "DMAC4_TX_POISON" }, |
|---|
| 2350 | | - { .irq_msk = BIT(29), .msg = "DMAC5_TX_POISON" }, |
|---|
| 2351 | | - { .irq_msk = BIT(30), .msg = "DMAC6_TX_POISON" }, |
|---|
| 2352 | | - { .irq_msk = BIT(31), .msg = "DMAC7_TX_POISON" }, |
|---|
| 2353 | | -}; |
|---|
| 2354 | | - |
|---|
| 2355 | | -static const struct hisi_sas_hw_error sas_ras_intr1_nfe[] = { |
|---|
| 2356 | | - { .irq_msk = BIT(0), .msg = "RXM_CFG_MEM3_ECC2B_INTR" }, |
|---|
| 2357 | | - { .irq_msk = BIT(1), .msg = "RXM_CFG_MEM2_ECC2B_INTR" }, |
|---|
| 2358 | | - { .irq_msk = BIT(2), .msg = "RXM_CFG_MEM1_ECC2B_INTR" }, |
|---|
| 2359 | | - { .irq_msk = BIT(3), .msg = "RXM_CFG_MEM0_ECC2B_INTR" }, |
|---|
| 2360 | | - { .irq_msk = BIT(4), .msg = "HGC_CQE_ECC2B_INTR" }, |
|---|
| 2361 | | - { .irq_msk = BIT(5), .msg = "LM_CFG_IOSTL_ECC2B_INTR" }, |
|---|
| 2362 | | - { .irq_msk = BIT(6), .msg = "LM_CFG_ITCTL_ECC2B_INTR" }, |
|---|
| 2363 | | - { .irq_msk = BIT(7), .msg = "HGC_ITCT_ECC2B_INTR" }, |
|---|
| 2364 | | - { .irq_msk = BIT(8), .msg = "HGC_IOST_ECC2B_INTR" }, |
|---|
| 2365 | | - { .irq_msk = BIT(9), .msg = "HGC_DQE_ECC2B_INTR" }, |
|---|
| 2366 | | - { .irq_msk = BIT(10), .msg = "DMAC0_RAM_ECC2B_INTR" }, |
|---|
| 2367 | | - { .irq_msk = BIT(11), .msg = "DMAC1_RAM_ECC2B_INTR" }, |
|---|
| 2368 | | - { .irq_msk = BIT(12), .msg = "DMAC2_RAM_ECC2B_INTR" }, |
|---|
| 2369 | | - { .irq_msk = BIT(13), .msg = "DMAC3_RAM_ECC2B_INTR" }, |
|---|
| 2370 | | - { .irq_msk = BIT(14), .msg = "DMAC4_RAM_ECC2B_INTR" }, |
|---|
| 2371 | | - { .irq_msk = BIT(15), .msg = "DMAC5_RAM_ECC2B_INTR" }, |
|---|
| 2372 | | - { .irq_msk = BIT(16), .msg = "DMAC6_RAM_ECC2B_INTR" }, |
|---|
| 2373 | | - { .irq_msk = BIT(17), .msg = "DMAC7_RAM_ECC2B_INTR" }, |
|---|
| 2374 | | - { .irq_msk = BIT(18), .msg = "OOO_RAM_ECC2B_INTR" }, |
|---|
| 2375 | | - { .irq_msk = BIT(20), .msg = "HGC_DQE_POISON_INTR" }, |
|---|
| 2376 | | - { .irq_msk = BIT(21), .msg = "HGC_IOST_POISON_INTR" }, |
|---|
| 2377 | | - { .irq_msk = BIT(22), .msg = "HGC_ITCT_POISON_INTR" }, |
|---|
| 2378 | | - { .irq_msk = BIT(23), .msg = "HGC_ITCT_NCQ_POISON_INTR" }, |
|---|
| 2379 | | - { .irq_msk = BIT(24), .msg = "DMAC0_RX_POISON" }, |
|---|
| 2380 | | - { .irq_msk = BIT(25), .msg = "DMAC1_RX_POISON" }, |
|---|
| 2381 | | - { .irq_msk = BIT(26), .msg = "DMAC2_RX_POISON" }, |
|---|
| 2382 | | - { .irq_msk = BIT(27), .msg = "DMAC3_RX_POISON" }, |
|---|
| 2383 | | - { .irq_msk = BIT(28), .msg = "DMAC4_RX_POISON" }, |
|---|
| 2384 | | - { .irq_msk = BIT(29), .msg = "DMAC5_RX_POISON" }, |
|---|
| 2385 | | - { .irq_msk = BIT(30), .msg = "DMAC6_RX_POISON" }, |
|---|
| 2386 | | - { .irq_msk = BIT(31), .msg = "DMAC7_RX_POISON" }, |
|---|
| 2387 | | -}; |
|---|
| 2388 | | - |
|---|
| 2389 | | -static const struct hisi_sas_hw_error sas_ras_intr2_nfe[] = { |
|---|
| 2390 | | - { .irq_msk = BIT(0), .msg = "DMAC0_AXI_BUS_ERR" }, |
|---|
| 2391 | | - { .irq_msk = BIT(1), .msg = "DMAC1_AXI_BUS_ERR" }, |
|---|
| 2392 | | - { .irq_msk = BIT(2), .msg = "DMAC2_AXI_BUS_ERR" }, |
|---|
| 2393 | | - { .irq_msk = BIT(3), .msg = "DMAC3_AXI_BUS_ERR" }, |
|---|
| 2394 | | - { .irq_msk = BIT(4), .msg = "DMAC4_AXI_BUS_ERR" }, |
|---|
| 2395 | | - { .irq_msk = BIT(5), .msg = "DMAC5_AXI_BUS_ERR" }, |
|---|
| 2396 | | - { .irq_msk = BIT(6), .msg = "DMAC6_AXI_BUS_ERR" }, |
|---|
| 2397 | | - { .irq_msk = BIT(7), .msg = "DMAC7_AXI_BUS_ERR" }, |
|---|
| 2398 | | - { .irq_msk = BIT(8), .msg = "DMAC0_FIFO_OMIT_ERR" }, |
|---|
| 2399 | | - { .irq_msk = BIT(9), .msg = "DMAC1_FIFO_OMIT_ERR" }, |
|---|
| 2400 | | - { .irq_msk = BIT(10), .msg = "DMAC2_FIFO_OMIT_ERR" }, |
|---|
| 2401 | | - { .irq_msk = BIT(11), .msg = "DMAC3_FIFO_OMIT_ERR" }, |
|---|
| 2402 | | - { .irq_msk = BIT(12), .msg = "DMAC4_FIFO_OMIT_ERR" }, |
|---|
| 2403 | | - { .irq_msk = BIT(13), .msg = "DMAC5_FIFO_OMIT_ERR" }, |
|---|
| 2404 | | - { .irq_msk = BIT(14), .msg = "DMAC6_FIFO_OMIT_ERR" }, |
|---|
| 2405 | | - { .irq_msk = BIT(15), .msg = "DMAC7_FIFO_OMIT_ERR" }, |
|---|
| 2406 | | - { .irq_msk = BIT(16), .msg = "HGC_RLSE_SLOT_UNMATCH" }, |
|---|
| 2407 | | - { .irq_msk = BIT(17), .msg = "HGC_LM_ADD_FCH_LIST_ERR" }, |
|---|
| 2408 | | - { .irq_msk = BIT(18), .msg = "HGC_AXI_BUS_ERR" }, |
|---|
| 2409 | | - { .irq_msk = BIT(19), .msg = "HGC_FIFO_OMIT_ERR" }, |
|---|
| 2410 | | -}; |
|---|
| 2411 | | - |
|---|
| 2412 | | -static bool process_non_fatal_error_v3_hw(struct hisi_hba *hisi_hba) |
|---|
| 2413 | | -{ |
|---|
| 2414 | | - struct device *dev = hisi_hba->dev; |
|---|
| 2415 | | - const struct hisi_sas_hw_error *ras_error; |
|---|
| 2416 | | - bool need_reset = false; |
|---|
| 2417 | | - u32 irq_value; |
|---|
| 2418 | | - int i; |
|---|
| 2419 | | - |
|---|
| 2420 | | - irq_value = hisi_sas_read32(hisi_hba, SAS_RAS_INTR0); |
|---|
| 2421 | | - for (i = 0; i < ARRAY_SIZE(sas_ras_intr0_nfe); i++) { |
|---|
| 2422 | | - ras_error = &sas_ras_intr0_nfe[i]; |
|---|
| 2423 | | - if (ras_error->irq_msk & irq_value) { |
|---|
| 2424 | | - dev_warn(dev, "SAS_RAS_INTR0: %s(irq_value=0x%x) found.\n", |
|---|
| 2425 | | - ras_error->msg, irq_value); |
|---|
| 2426 | | - need_reset = true; |
|---|
| 2427 | | - } |
|---|
| 2428 | | - } |
|---|
| 2429 | | - hisi_sas_write32(hisi_hba, SAS_RAS_INTR0, irq_value); |
|---|
| 2430 | | - |
|---|
| 2431 | | - irq_value = hisi_sas_read32(hisi_hba, SAS_RAS_INTR1); |
|---|
| 2432 | | - for (i = 0; i < ARRAY_SIZE(sas_ras_intr1_nfe); i++) { |
|---|
| 2433 | | - ras_error = &sas_ras_intr1_nfe[i]; |
|---|
| 2434 | | - if (ras_error->irq_msk & irq_value) { |
|---|
| 2435 | | - dev_warn(dev, "SAS_RAS_INTR1: %s(irq_value=0x%x) found.\n", |
|---|
| 2436 | | - ras_error->msg, irq_value); |
|---|
| 2437 | | - need_reset = true; |
|---|
| 2438 | | - } |
|---|
| 2439 | | - } |
|---|
| 2440 | | - hisi_sas_write32(hisi_hba, SAS_RAS_INTR1, irq_value); |
|---|
| 2441 | | - |
|---|
| 2442 | | - irq_value = hisi_sas_read32(hisi_hba, SAS_RAS_INTR2); |
|---|
| 2443 | | - for (i = 0; i < ARRAY_SIZE(sas_ras_intr2_nfe); i++) { |
|---|
| 2444 | | - ras_error = &sas_ras_intr2_nfe[i]; |
|---|
| 2445 | | - if (ras_error->irq_msk & irq_value) { |
|---|
| 2446 | | - dev_warn(dev, "SAS_RAS_INTR2: %s(irq_value=0x%x) found.\n", |
|---|
| 2447 | | - ras_error->msg, irq_value); |
|---|
| 2448 | | - need_reset = true; |
|---|
| 2449 | | - } |
|---|
| 2450 | | - } |
|---|
| 2451 | | - hisi_sas_write32(hisi_hba, SAS_RAS_INTR2, irq_value); |
|---|
| 2452 | | - |
|---|
| 2453 | | - return need_reset; |
|---|
| 2454 | | -} |
|---|
| 2455 | | - |
|---|
| 2456 | | -static pci_ers_result_t hisi_sas_error_detected_v3_hw(struct pci_dev *pdev, |
|---|
| 2457 | | - pci_channel_state_t state) |
|---|
| 2458 | | -{ |
|---|
| 2459 | | - struct sas_ha_struct *sha = pci_get_drvdata(pdev); |
|---|
| 2460 | | - struct hisi_hba *hisi_hba = sha->lldd_ha; |
|---|
| 2461 | | - struct device *dev = hisi_hba->dev; |
|---|
| 2462 | | - |
|---|
| 2463 | | - dev_info(dev, "PCI error: detected callback, state(%d)!!\n", state); |
|---|
| 2464 | | - if (state == pci_channel_io_perm_failure) |
|---|
| 2465 | | - return PCI_ERS_RESULT_DISCONNECT; |
|---|
| 2466 | | - |
|---|
| 2467 | | - if (process_non_fatal_error_v3_hw(hisi_hba)) |
|---|
| 2468 | | - return PCI_ERS_RESULT_NEED_RESET; |
|---|
| 2469 | | - |
|---|
| 2470 | | - return PCI_ERS_RESULT_CAN_RECOVER; |
|---|
| 2471 | | -} |
|---|
| 2472 | | - |
|---|
| 2473 | | -static pci_ers_result_t hisi_sas_mmio_enabled_v3_hw(struct pci_dev *pdev) |
|---|
| 2474 | | -{ |
|---|
| 2475 | | - return PCI_ERS_RESULT_RECOVERED; |
|---|
| 2476 | | -} |
|---|
| 2477 | | - |
|---|
| 2478 | | -static pci_ers_result_t hisi_sas_slot_reset_v3_hw(struct pci_dev *pdev) |
|---|
| 2479 | | -{ |
|---|
| 2480 | | - struct sas_ha_struct *sha = pci_get_drvdata(pdev); |
|---|
| 2481 | | - struct hisi_hba *hisi_hba = sha->lldd_ha; |
|---|
| 2482 | | - struct device *dev = hisi_hba->dev; |
|---|
| 2483 | | - HISI_SAS_DECLARE_RST_WORK_ON_STACK(r); |
|---|
| 2484 | | - |
|---|
| 2485 | | - dev_info(dev, "PCI error: slot reset callback!!\n"); |
|---|
| 2486 | | - queue_work(hisi_hba->wq, &r.work); |
|---|
| 2487 | | - wait_for_completion(r.completion); |
|---|
| 2488 | | - if (r.done) |
|---|
| 2489 | | - return PCI_ERS_RESULT_RECOVERED; |
|---|
| 2490 | | - |
|---|
| 2491 | | - return PCI_ERS_RESULT_DISCONNECT; |
|---|
| 2492 | 3401 | } |
|---|
| 2493 | 3402 | |
|---|
| 2494 | 3403 | static void hisi_sas_reset_prepare_v3_hw(struct pci_dev *pdev) |
|---|
| .. | .. |
|---|
| 2531 | 3440 | hip08, |
|---|
| 2532 | 3441 | }; |
|---|
| 2533 | 3442 | |
|---|
| 2534 | | -static int hisi_sas_v3_suspend(struct pci_dev *pdev, pm_message_t state) |
|---|
| 3443 | +static int _suspend_v3_hw(struct device *device) |
|---|
| 2535 | 3444 | { |
|---|
| 3445 | + struct pci_dev *pdev = to_pci_dev(device); |
|---|
| 2536 | 3446 | struct sas_ha_struct *sha = pci_get_drvdata(pdev); |
|---|
| 2537 | 3447 | struct hisi_hba *hisi_hba = sha->lldd_ha; |
|---|
| 2538 | 3448 | struct device *dev = hisi_hba->dev; |
|---|
| 2539 | 3449 | struct Scsi_Host *shost = hisi_hba->shost; |
|---|
| 2540 | | - u32 device_state; |
|---|
| 3450 | + pci_power_t device_state; |
|---|
| 2541 | 3451 | int rc; |
|---|
| 2542 | 3452 | |
|---|
| 2543 | 3453 | if (!pdev->pm_cap) { |
|---|
| .. | .. |
|---|
| 2563 | 3473 | |
|---|
| 2564 | 3474 | hisi_sas_init_mem(hisi_hba); |
|---|
| 2565 | 3475 | |
|---|
| 2566 | | - device_state = pci_choose_state(pdev, state); |
|---|
| 3476 | + device_state = pci_choose_state(pdev, PMSG_SUSPEND); |
|---|
| 2567 | 3477 | dev_warn(dev, "entering operating state [D%d]\n", |
|---|
| 2568 | 3478 | device_state); |
|---|
| 2569 | 3479 | pci_save_state(pdev); |
|---|
| .. | .. |
|---|
| 2576 | 3486 | return 0; |
|---|
| 2577 | 3487 | } |
|---|
| 2578 | 3488 | |
|---|
| 2579 | | -static int hisi_sas_v3_resume(struct pci_dev *pdev) |
|---|
| 3489 | +static int _resume_v3_hw(struct device *device) |
|---|
| 2580 | 3490 | { |
|---|
| 3491 | + struct pci_dev *pdev = to_pci_dev(device); |
|---|
| 2581 | 3492 | struct sas_ha_struct *sha = pci_get_drvdata(pdev); |
|---|
| 2582 | 3493 | struct hisi_hba *hisi_hba = sha->lldd_ha; |
|---|
| 2583 | 3494 | struct Scsi_Host *shost = hisi_hba->shost; |
|---|
| 2584 | 3495 | struct device *dev = hisi_hba->dev; |
|---|
| 2585 | 3496 | unsigned int rc; |
|---|
| 2586 | | - u32 device_state = pdev->current_state; |
|---|
| 3497 | + pci_power_t device_state = pdev->current_state; |
|---|
| 2587 | 3498 | |
|---|
| 2588 | 3499 | dev_warn(dev, "resuming from operating state [D%d]\n", |
|---|
| 2589 | | - device_state); |
|---|
| 3500 | + device_state); |
|---|
| 2590 | 3501 | pci_set_power_state(pdev, PCI_D0); |
|---|
| 2591 | 3502 | pci_enable_wake(pdev, PCI_D0, 0); |
|---|
| 2592 | 3503 | pci_restore_state(pdev); |
|---|
| 2593 | 3504 | rc = pci_enable_device(pdev); |
|---|
| 2594 | | - if (rc) |
|---|
| 3505 | + if (rc) { |
|---|
| 2595 | 3506 | dev_err(dev, "enable device failed during resume (%d)\n", rc); |
|---|
| 3507 | + return rc; |
|---|
| 3508 | + } |
|---|
| 2596 | 3509 | |
|---|
| 2597 | 3510 | pci_set_master(pdev); |
|---|
| 2598 | 3511 | scsi_unblock_requests(shost); |
|---|
| 2599 | 3512 | clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); |
|---|
| 2600 | 3513 | |
|---|
| 2601 | 3514 | sas_prep_resume_ha(sha); |
|---|
| 2602 | | - init_reg_v3_hw(hisi_hba); |
|---|
| 3515 | + rc = hw_init_v3_hw(hisi_hba); |
|---|
| 3516 | + if (rc) { |
|---|
| 3517 | + scsi_remove_host(shost); |
|---|
| 3518 | + pci_disable_device(pdev); |
|---|
| 3519 | + return rc; |
|---|
| 3520 | + } |
|---|
| 2603 | 3521 | hisi_hba->hw->phys_init(hisi_hba); |
|---|
| 2604 | 3522 | sas_resume_ha(sha); |
|---|
| 2605 | 3523 | clear_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags); |
|---|
| 2606 | 3524 | |
|---|
| 2607 | 3525 | return 0; |
|---|
| 3526 | +} |
|---|
| 3527 | + |
|---|
| 3528 | +static int suspend_v3_hw(struct device *device) |
|---|
| 3529 | +{ |
|---|
| 3530 | + struct pci_dev *pdev = to_pci_dev(device); |
|---|
| 3531 | + struct sas_ha_struct *sha = pci_get_drvdata(pdev); |
|---|
| 3532 | + struct hisi_hba *hisi_hba = sha->lldd_ha; |
|---|
| 3533 | + int rc; |
|---|
| 3534 | + |
|---|
| 3535 | + set_bit(HISI_SAS_PM_BIT, &hisi_hba->flags); |
|---|
| 3536 | + |
|---|
| 3537 | + rc = _suspend_v3_hw(device); |
|---|
| 3538 | + if (rc) |
|---|
| 3539 | + clear_bit(HISI_SAS_PM_BIT, &hisi_hba->flags); |
|---|
| 3540 | + |
|---|
| 3541 | + return rc; |
|---|
| 3542 | +} |
|---|
| 3543 | + |
|---|
| 3544 | +static int resume_v3_hw(struct device *device) |
|---|
| 3545 | +{ |
|---|
| 3546 | + struct pci_dev *pdev = to_pci_dev(device); |
|---|
| 3547 | + struct sas_ha_struct *sha = pci_get_drvdata(pdev); |
|---|
| 3548 | + struct hisi_hba *hisi_hba = sha->lldd_ha; |
|---|
| 3549 | + int rc = _resume_v3_hw(device); |
|---|
| 3550 | + |
|---|
| 3551 | + clear_bit(HISI_SAS_PM_BIT, &hisi_hba->flags); |
|---|
| 3552 | + |
|---|
| 3553 | + return rc; |
|---|
| 2608 | 3554 | } |
|---|
| 2609 | 3555 | |
|---|
| 2610 | 3556 | static const struct pci_device_id sas_v3_pci_table[] = { |
|---|
| .. | .. |
|---|
| 2614 | 3560 | MODULE_DEVICE_TABLE(pci, sas_v3_pci_table); |
|---|
| 2615 | 3561 | |
|---|
| 2616 | 3562 | static const struct pci_error_handlers hisi_sas_err_handler = { |
|---|
| 2617 | | - .error_detected = hisi_sas_error_detected_v3_hw, |
|---|
| 2618 | | - .mmio_enabled = hisi_sas_mmio_enabled_v3_hw, |
|---|
| 2619 | | - .slot_reset = hisi_sas_slot_reset_v3_hw, |
|---|
| 2620 | 3563 | .reset_prepare = hisi_sas_reset_prepare_v3_hw, |
|---|
| 2621 | 3564 | .reset_done = hisi_sas_reset_done_v3_hw, |
|---|
| 3565 | +}; |
|---|
| 3566 | + |
|---|
| 3567 | +static int runtime_suspend_v3_hw(struct device *dev) |
|---|
| 3568 | +{ |
|---|
| 3569 | + return suspend_v3_hw(dev); |
|---|
| 3570 | +} |
|---|
| 3571 | + |
|---|
| 3572 | +static int runtime_resume_v3_hw(struct device *dev) |
|---|
| 3573 | +{ |
|---|
| 3574 | + return resume_v3_hw(dev); |
|---|
| 3575 | +} |
|---|
| 3576 | + |
|---|
| 3577 | +static const struct dev_pm_ops hisi_sas_v3_pm_ops = { |
|---|
| 3578 | + SET_SYSTEM_SLEEP_PM_OPS(suspend_v3_hw, resume_v3_hw) |
|---|
| 3579 | + SET_RUNTIME_PM_OPS(runtime_suspend_v3_hw, |
|---|
| 3580 | + runtime_resume_v3_hw, NULL) |
|---|
| 2622 | 3581 | }; |
|---|
| 2623 | 3582 | |
|---|
| 2624 | 3583 | static struct pci_driver sas_v3_pci_driver = { |
|---|
| .. | .. |
|---|
| 2626 | 3585 | .id_table = sas_v3_pci_table, |
|---|
| 2627 | 3586 | .probe = hisi_sas_v3_probe, |
|---|
| 2628 | 3587 | .remove = hisi_sas_v3_remove, |
|---|
| 2629 | | - .suspend = hisi_sas_v3_suspend, |
|---|
| 2630 | | - .resume = hisi_sas_v3_resume, |
|---|
| 2631 | 3588 | .err_handler = &hisi_sas_err_handler, |
|---|
| 3589 | + .driver.pm = &hisi_sas_v3_pm_ops, |
|---|
| 2632 | 3590 | }; |
|---|
| 2633 | 3591 | |
|---|
| 2634 | 3592 | module_pci_driver(sas_v3_pci_driver); |
|---|
| 3593 | +module_param_named(intr_conv, hisi_sas_intr_conv, bool, 0444); |
|---|
| 2635 | 3594 | |
|---|
| 2636 | 3595 | MODULE_LICENSE("GPL"); |
|---|
| 2637 | 3596 | MODULE_AUTHOR("John Garry <john.garry@huawei.com>"); |
|---|