.. | .. |
---|
| 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) |
---|
.. | .. |
---|
293 | 392 | #define CMPLT_HDR_ERROR_PHASE_MSK (0xff << CMPLT_HDR_ERROR_PHASE_OFF) |
---|
294 | 393 | #define CMPLT_HDR_RSPNS_XFRD_OFF 10 |
---|
295 | 394 | #define CMPLT_HDR_RSPNS_XFRD_MSK (0x1 << CMPLT_HDR_RSPNS_XFRD_OFF) |
---|
| 395 | +#define CMPLT_HDR_RSPNS_GOOD_OFF 11 |
---|
| 396 | +#define CMPLT_HDR_RSPNS_GOOD_MSK (0x1 << CMPLT_HDR_RSPNS_GOOD_OFF) |
---|
296 | 397 | #define CMPLT_HDR_ERX_OFF 12 |
---|
297 | 398 | #define CMPLT_HDR_ERX_MSK (0x1 << CMPLT_HDR_ERX_OFF) |
---|
298 | 399 | #define CMPLT_HDR_ABORT_STAT_OFF 13 |
---|
.. | .. |
---|
331 | 432 | #define ITCT_HDR_RTOLT_OFF 48 |
---|
332 | 433 | #define ITCT_HDR_RTOLT_MSK (0xffffULL << ITCT_HDR_RTOLT_OFF) |
---|
333 | 434 | |
---|
| 435 | +struct hisi_sas_protect_iu_v3_hw { |
---|
| 436 | + u32 dw0; |
---|
| 437 | + u32 lbrtcv; |
---|
| 438 | + u32 lbrtgv; |
---|
| 439 | + u32 dw3; |
---|
| 440 | + u32 dw4; |
---|
| 441 | + u32 dw5; |
---|
| 442 | + u32 rsv; |
---|
| 443 | +}; |
---|
| 444 | + |
---|
334 | 445 | struct hisi_sas_complete_v3_hdr { |
---|
335 | 446 | __le32 dw0; |
---|
336 | 447 | __le32 dw1; |
---|
.. | .. |
---|
356 | 467 | #define RX_DATA_LEN_UNDERFLOW_OFF 6 |
---|
357 | 468 | #define RX_DATA_LEN_UNDERFLOW_MSK (1 << RX_DATA_LEN_UNDERFLOW_OFF) |
---|
358 | 469 | |
---|
| 470 | +#define RX_FIS_STATUS_ERR_OFF 0 |
---|
| 471 | +#define RX_FIS_STATUS_ERR_MSK (1 << RX_FIS_STATUS_ERR_OFF) |
---|
| 472 | + |
---|
359 | 473 | #define HISI_SAS_COMMAND_ENTRIES_V3_HW 4096 |
---|
360 | 474 | #define HISI_SAS_MSI_COUNT_V3_HW 32 |
---|
361 | 475 | |
---|
.. | .. |
---|
370 | 484 | ((fis.command == ATA_CMD_DEV_RESET) && \ |
---|
371 | 485 | ((fis.control & ATA_SRST) != 0))) |
---|
372 | 486 | |
---|
| 487 | +#define T10_INSRT_EN_OFF 0 |
---|
| 488 | +#define T10_INSRT_EN_MSK (1 << T10_INSRT_EN_OFF) |
---|
| 489 | +#define T10_RMV_EN_OFF 1 |
---|
| 490 | +#define T10_RMV_EN_MSK (1 << T10_RMV_EN_OFF) |
---|
| 491 | +#define T10_RPLC_EN_OFF 2 |
---|
| 492 | +#define T10_RPLC_EN_MSK (1 << T10_RPLC_EN_OFF) |
---|
| 493 | +#define T10_CHK_EN_OFF 3 |
---|
| 494 | +#define T10_CHK_EN_MSK (1 << T10_CHK_EN_OFF) |
---|
| 495 | +#define INCR_LBRT_OFF 5 |
---|
| 496 | +#define INCR_LBRT_MSK (1 << INCR_LBRT_OFF) |
---|
| 497 | +#define USR_DATA_BLOCK_SZ_OFF 20 |
---|
| 498 | +#define USR_DATA_BLOCK_SZ_MSK (0x3 << USR_DATA_BLOCK_SZ_OFF) |
---|
| 499 | +#define T10_CHK_MSK_OFF 16 |
---|
| 500 | +#define T10_CHK_REF_TAG_MSK (0xf0 << T10_CHK_MSK_OFF) |
---|
| 501 | +#define T10_CHK_APP_TAG_MSK (0xc << T10_CHK_MSK_OFF) |
---|
| 502 | + |
---|
| 503 | +#define BASE_VECTORS_V3_HW 16 |
---|
| 504 | +#define MIN_AFFINE_VECTORS_V3_HW (BASE_VECTORS_V3_HW + 1) |
---|
| 505 | + |
---|
| 506 | +#define CHNL_INT_STS_MSK 0xeeeeeeee |
---|
| 507 | +#define CHNL_INT_STS_PHY_MSK 0xe |
---|
| 508 | +#define CHNL_INT_STS_INT0_MSK BIT(1) |
---|
| 509 | +#define CHNL_INT_STS_INT1_MSK BIT(2) |
---|
| 510 | +#define CHNL_INT_STS_INT2_MSK BIT(3) |
---|
| 511 | +#define CHNL_WIDTH 4 |
---|
| 512 | + |
---|
| 513 | +enum { |
---|
| 514 | + DSM_FUNC_ERR_HANDLE_MSI = 0, |
---|
| 515 | +}; |
---|
| 516 | + |
---|
| 517 | +static bool hisi_sas_intr_conv; |
---|
| 518 | +MODULE_PARM_DESC(intr_conv, "interrupt converge enable (0-1)"); |
---|
| 519 | + |
---|
| 520 | +/* permit overriding the host protection capabilities mask (EEDP/T10 PI) */ |
---|
| 521 | +static int prot_mask; |
---|
| 522 | +module_param(prot_mask, int, 0444); |
---|
| 523 | +MODULE_PARM_DESC(prot_mask, " host protection capabilities mask, def=0x0 "); |
---|
| 524 | + |
---|
| 525 | +static bool auto_affine_msi_experimental; |
---|
| 526 | +module_param(auto_affine_msi_experimental, bool, 0444); |
---|
| 527 | +MODULE_PARM_DESC(auto_affine_msi_experimental, "Enable auto-affinity of MSI IRQs as experimental:\n" |
---|
| 528 | + "default is off"); |
---|
| 529 | + |
---|
373 | 530 | static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off) |
---|
374 | 531 | { |
---|
375 | 532 | void __iomem *regs = hisi_hba->regs + off; |
---|
376 | 533 | |
---|
377 | 534 | 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 | 535 | } |
---|
386 | 536 | |
---|
387 | 537 | static void hisi_sas_write32(struct hisi_hba *hisi_hba, u32 off, u32 val) |
---|
.. | .. |
---|
423 | 573 | |
---|
424 | 574 | static void init_reg_v3_hw(struct hisi_hba *hisi_hba) |
---|
425 | 575 | { |
---|
426 | | - struct pci_dev *pdev = hisi_hba->pci_dev; |
---|
427 | | - int i; |
---|
| 576 | + int i, j; |
---|
428 | 577 | |
---|
429 | 578 | /* Global registers init */ |
---|
430 | 579 | hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, |
---|
431 | 580 | (u32)((1ULL << hisi_hba->queue_count) - 1)); |
---|
| 581 | + hisi_sas_write32(hisi_hba, SAS_AXI_USER3, 0); |
---|
432 | 582 | hisi_sas_write32(hisi_hba, CFG_MAX_TAG, 0xfff0400); |
---|
433 | 583 | hisi_sas_write32(hisi_hba, HGC_SAS_TXFAIL_RETRY_CTRL, 0x108); |
---|
| 584 | + hisi_sas_write32(hisi_hba, CFG_AGING_TIME, 0x1); |
---|
434 | 585 | hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x1); |
---|
435 | 586 | hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, 0x1); |
---|
436 | 587 | hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, 0x1); |
---|
| 588 | + hisi_sas_write32(hisi_hba, CQ_INT_CONVERGE_EN, |
---|
| 589 | + hisi_sas_intr_conv); |
---|
437 | 590 | hisi_sas_write32(hisi_hba, OQ_INT_SRC, 0xffff); |
---|
438 | 591 | hisi_sas_write32(hisi_hba, ENT_INT_SRC1, 0xffffffff); |
---|
439 | 592 | hisi_sas_write32(hisi_hba, ENT_INT_SRC2, 0xffffffff); |
---|
440 | 593 | hisi_sas_write32(hisi_hba, ENT_INT_SRC3, 0xffffffff); |
---|
441 | 594 | hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, 0xfefefefe); |
---|
442 | 595 | 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); |
---|
| 596 | + hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xffc220ff); |
---|
447 | 597 | hisi_sas_write32(hisi_hba, CHNL_PHYUPDOWN_INT_MSK, 0x0); |
---|
448 | 598 | hisi_sas_write32(hisi_hba, CHNL_ENT_INT_MSK, 0x0); |
---|
449 | 599 | hisi_sas_write32(hisi_hba, HGC_COM_INT_MSK, 0x0); |
---|
450 | | - hisi_sas_write32(hisi_hba, SAS_ECC_INTR_MSK, 0x0); |
---|
| 600 | + hisi_sas_write32(hisi_hba, SAS_ECC_INTR_MSK, 0x155555); |
---|
451 | 601 | hisi_sas_write32(hisi_hba, AWQOS_AWCACHE_CFG, 0xf0f0); |
---|
452 | 602 | hisi_sas_write32(hisi_hba, ARQOS_ARCACHE_CFG, 0xf0f0); |
---|
453 | 603 | for (i = 0; i < hisi_hba->queue_count; i++) |
---|
454 | | - hisi_sas_write32(hisi_hba, OQ0_INT_SRC_MSK+0x4*i, 0); |
---|
| 604 | + hisi_sas_write32(hisi_hba, OQ0_INT_SRC_MSK + 0x4 * i, 0); |
---|
455 | 605 | |
---|
456 | 606 | hisi_sas_write32(hisi_hba, HYPER_STREAM_ID_EN_CFG, 1); |
---|
457 | 607 | |
---|
458 | 608 | for (i = 0; i < hisi_hba->n_phy; i++) { |
---|
| 609 | + enum sas_linkrate max; |
---|
459 | 610 | struct hisi_sas_phy *phy = &hisi_hba->phy[i]; |
---|
460 | 611 | struct asd_sas_phy *sas_phy = &phy->sas_phy; |
---|
461 | | - u32 prog_phy_link_rate = 0x800; |
---|
| 612 | + u32 prog_phy_link_rate = hisi_sas_phy_read32(hisi_hba, i, |
---|
| 613 | + PROG_PHY_LINK_RATE); |
---|
462 | 614 | |
---|
| 615 | + prog_phy_link_rate &= ~CFG_PROG_PHY_LINK_RATE_MSK; |
---|
463 | 616 | 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 | | - } |
---|
| 617 | + SAS_LINK_RATE_1_5_GBPS)) |
---|
| 618 | + max = SAS_LINK_RATE_12_0_GBPS; |
---|
| 619 | + else |
---|
| 620 | + max = sas_phy->phy->maximum_linkrate; |
---|
| 621 | + prog_phy_link_rate |= hisi_sas_get_prog_phy_linkrate_mask(max); |
---|
473 | 622 | hisi_sas_phy_write32(hisi_hba, i, PROG_PHY_LINK_RATE, |
---|
474 | 623 | prog_phy_link_rate); |
---|
| 624 | + hisi_sas_phy_write32(hisi_hba, i, SERDES_CFG, 0xffc00); |
---|
475 | 625 | hisi_sas_phy_write32(hisi_hba, i, SAS_RX_TRAIN_TIMER, 0x13e80); |
---|
476 | 626 | hisi_sas_phy_write32(hisi_hba, i, CHL_INT0, 0xffffffff); |
---|
477 | 627 | hisi_sas_phy_write32(hisi_hba, i, CHL_INT1, 0xffffffff); |
---|
478 | 628 | hisi_sas_phy_write32(hisi_hba, i, CHL_INT2, 0xffffffff); |
---|
479 | 629 | 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); |
---|
| 630 | + hisi_sas_phy_write32(hisi_hba, i, CHL_INT1_MSK, 0xf2057fff); |
---|
486 | 631 | hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0xffffbfe); |
---|
487 | 632 | hisi_sas_phy_write32(hisi_hba, i, PHY_CTRL_RDY_MSK, 0x0); |
---|
488 | 633 | hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_NOT_RDY_MSK, 0x0); |
---|
.. | .. |
---|
493 | 638 | hisi_sas_phy_write32(hisi_hba, i, STP_LINK_TIMER, 0x7f7a120); |
---|
494 | 639 | hisi_sas_phy_write32(hisi_hba, i, CON_CFG_DRIVER, 0x2a0a01); |
---|
495 | 640 | hisi_sas_phy_write32(hisi_hba, i, SAS_SSP_CON_TIMER_CFG, 0x32); |
---|
| 641 | + hisi_sas_phy_write32(hisi_hba, i, SAS_EC_INT_COAL_TIME, |
---|
| 642 | + 0x30f4240); |
---|
496 | 643 | /* used for 12G negotiate */ |
---|
497 | 644 | hisi_sas_phy_write32(hisi_hba, i, COARSETUNE_TIME, 0x1e); |
---|
| 645 | + hisi_sas_phy_write32(hisi_hba, i, AIP_LIMIT, 0x2ffff); |
---|
| 646 | + |
---|
| 647 | + /* get default FFE configuration for BIST */ |
---|
| 648 | + for (j = 0; j < FFE_CFG_MAX; j++) { |
---|
| 649 | + u32 val = hisi_sas_phy_read32(hisi_hba, i, |
---|
| 650 | + TXDEEMPH_G1 + (j * 0x4)); |
---|
| 651 | + hisi_hba->debugfs_bist_ffe[i][j] = val; |
---|
| 652 | + } |
---|
498 | 653 | } |
---|
499 | 654 | |
---|
500 | 655 | for (i = 0; i < hisi_hba->queue_count; i++) { |
---|
.. | .. |
---|
619 | 774 | struct domain_device *parent_dev = device->parent; |
---|
620 | 775 | struct asd_sas_port *sas_port = device->port; |
---|
621 | 776 | struct hisi_sas_port *port = to_hisi_sas_port(sas_port); |
---|
| 777 | + u64 sas_addr; |
---|
622 | 778 | |
---|
623 | 779 | memset(itct, 0, sizeof(*itct)); |
---|
624 | 780 | |
---|
.. | .. |
---|
632 | 788 | break; |
---|
633 | 789 | case SAS_SATA_DEV: |
---|
634 | 790 | case SAS_SATA_PENDING: |
---|
635 | | - if (parent_dev && DEV_IS_EXPANDER(parent_dev->dev_type)) |
---|
| 791 | + if (parent_dev && dev_is_expander(parent_dev->dev_type)) |
---|
636 | 792 | qw0 = HISI_SAS_DEV_TYPE_STP << ITCT_HDR_DEV_TYPE_OFF; |
---|
637 | 793 | else |
---|
638 | 794 | qw0 = HISI_SAS_DEV_TYPE_SATA << ITCT_HDR_DEV_TYPE_OFF; |
---|
.. | .. |
---|
651 | 807 | itct->qw0 = cpu_to_le64(qw0); |
---|
652 | 808 | |
---|
653 | 809 | /* qw1 */ |
---|
654 | | - memcpy(&itct->sas_addr, device->sas_addr, SAS_ADDR_SIZE); |
---|
655 | | - itct->sas_addr = __swab64(itct->sas_addr); |
---|
| 810 | + memcpy(&sas_addr, device->sas_addr, SAS_ADDR_SIZE); |
---|
| 811 | + itct->sas_addr = cpu_to_le64(__swab64(sas_addr)); |
---|
656 | 812 | |
---|
657 | 813 | /* qw2 */ |
---|
658 | 814 | if (!dev_is_sata(device)) |
---|
.. | .. |
---|
660 | 816 | (0x1ULL << ITCT_HDR_RTOLT_OFF)); |
---|
661 | 817 | } |
---|
662 | 818 | |
---|
663 | | -static void clear_itct_v3_hw(struct hisi_hba *hisi_hba, |
---|
664 | | - struct hisi_sas_device *sas_dev) |
---|
| 819 | +static int clear_itct_v3_hw(struct hisi_hba *hisi_hba, |
---|
| 820 | + struct hisi_sas_device *sas_dev) |
---|
665 | 821 | { |
---|
666 | 822 | DECLARE_COMPLETION_ONSTACK(completion); |
---|
667 | 823 | u64 dev_id = sas_dev->device_id; |
---|
668 | 824 | struct hisi_sas_itct *itct = &hisi_hba->itct[dev_id]; |
---|
669 | 825 | u32 reg_val = hisi_sas_read32(hisi_hba, ENT_INT_SRC3); |
---|
| 826 | + struct device *dev = hisi_hba->dev; |
---|
670 | 827 | |
---|
671 | 828 | sas_dev->completion = &completion; |
---|
672 | 829 | |
---|
.. | .. |
---|
675 | 832 | hisi_sas_write32(hisi_hba, ENT_INT_SRC3, |
---|
676 | 833 | ENT_INT_SRC3_ITC_INT_MSK); |
---|
677 | 834 | |
---|
678 | | - /* clear the itct table*/ |
---|
| 835 | + /* clear the itct table */ |
---|
679 | 836 | reg_val = ITCT_CLR_EN_MSK | (dev_id & ITCT_DEV_MSK); |
---|
680 | 837 | hisi_sas_write32(hisi_hba, ITCT_CLR, reg_val); |
---|
681 | 838 | |
---|
682 | | - wait_for_completion(sas_dev->completion); |
---|
| 839 | + if (!wait_for_completion_timeout(sas_dev->completion, |
---|
| 840 | + CLEAR_ITCT_TIMEOUT * HZ)) { |
---|
| 841 | + dev_warn(dev, "failed to clear ITCT\n"); |
---|
| 842 | + return -ETIMEDOUT; |
---|
| 843 | + } |
---|
| 844 | + |
---|
683 | 845 | memset(itct, 0, sizeof(struct hisi_sas_itct)); |
---|
| 846 | + return 0; |
---|
684 | 847 | } |
---|
685 | 848 | |
---|
686 | 849 | static void dereg_device_v3_hw(struct hisi_hba *hisi_hba, |
---|
.. | .. |
---|
745 | 908 | static int hw_init_v3_hw(struct hisi_hba *hisi_hba) |
---|
746 | 909 | { |
---|
747 | 910 | struct device *dev = hisi_hba->dev; |
---|
| 911 | + struct acpi_device *acpi_dev; |
---|
| 912 | + union acpi_object *obj; |
---|
| 913 | + guid_t guid; |
---|
748 | 914 | int rc; |
---|
749 | 915 | |
---|
750 | 916 | rc = reset_hw_v3_hw(hisi_hba); |
---|
751 | 917 | if (rc) { |
---|
752 | | - dev_err(dev, "hisi_sas_reset_hw failed, rc=%d", rc); |
---|
| 918 | + dev_err(dev, "hisi_sas_reset_hw failed, rc=%d\n", rc); |
---|
753 | 919 | return rc; |
---|
754 | 920 | } |
---|
755 | 921 | |
---|
756 | 922 | msleep(100); |
---|
757 | 923 | init_reg_v3_hw(hisi_hba); |
---|
758 | 924 | |
---|
| 925 | + if (guid_parse("D5918B4B-37AE-4E10-A99F-E5E8A6EF4C1F", &guid)) { |
---|
| 926 | + dev_err(dev, "Parse GUID failed\n"); |
---|
| 927 | + return -EINVAL; |
---|
| 928 | + } |
---|
| 929 | + |
---|
| 930 | + /* |
---|
| 931 | + * This DSM handles some hardware-related configurations: |
---|
| 932 | + * 1. Switch over to MSI error handling in kernel |
---|
| 933 | + * 2. BIOS *may* reset some register values through this method |
---|
| 934 | + */ |
---|
| 935 | + obj = acpi_evaluate_dsm(ACPI_HANDLE(dev), &guid, 0, |
---|
| 936 | + DSM_FUNC_ERR_HANDLE_MSI, NULL); |
---|
| 937 | + if (!obj) |
---|
| 938 | + dev_warn(dev, "can not find DSM method, ignore\n"); |
---|
| 939 | + else |
---|
| 940 | + ACPI_FREE(obj); |
---|
| 941 | + |
---|
| 942 | + acpi_dev = ACPI_COMPANION(dev); |
---|
| 943 | + if (!acpi_device_power_manageable(acpi_dev)) |
---|
| 944 | + dev_notice(dev, "neither _PS0 nor _PR0 is defined\n"); |
---|
759 | 945 | return 0; |
---|
760 | 946 | } |
---|
761 | 947 | |
---|
.. | .. |
---|
771 | 957 | static void disable_phy_v3_hw(struct hisi_hba *hisi_hba, int phy_no) |
---|
772 | 958 | { |
---|
773 | 959 | u32 cfg = hisi_sas_phy_read32(hisi_hba, phy_no, PHY_CFG); |
---|
| 960 | + u32 irq_msk = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT2_MSK); |
---|
| 961 | + static const u32 msk = BIT(CHL_INT2_RX_DISP_ERR_OFF) | |
---|
| 962 | + BIT(CHL_INT2_RX_CODE_ERR_OFF) | |
---|
| 963 | + BIT(CHL_INT2_RX_INVLD_DW_OFF); |
---|
774 | 964 | u32 state; |
---|
| 965 | + |
---|
| 966 | + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2_MSK, msk | irq_msk); |
---|
775 | 967 | |
---|
776 | 968 | cfg &= ~PHY_CFG_ENA_MSK; |
---|
777 | 969 | hisi_sas_phy_write32(hisi_hba, phy_no, PHY_CFG, cfg); |
---|
.. | .. |
---|
783 | 975 | cfg |= PHY_CFG_PHY_RST_MSK; |
---|
784 | 976 | hisi_sas_phy_write32(hisi_hba, phy_no, PHY_CFG, cfg); |
---|
785 | 977 | } |
---|
| 978 | + |
---|
| 979 | + udelay(1); |
---|
| 980 | + |
---|
| 981 | + hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_INVLD_DW); |
---|
| 982 | + hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_DISP_ERR); |
---|
| 983 | + hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_CODE_ERR); |
---|
| 984 | + |
---|
| 985 | + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2, msk); |
---|
| 986 | + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2_MSK, irq_msk); |
---|
786 | 987 | } |
---|
787 | 988 | |
---|
788 | 989 | static void start_phy_v3_hw(struct hisi_hba *hisi_hba, int phy_no) |
---|
.. | .. |
---|
797 | 998 | struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; |
---|
798 | 999 | u32 txid_auto; |
---|
799 | 1000 | |
---|
800 | | - disable_phy_v3_hw(hisi_hba, phy_no); |
---|
| 1001 | + hisi_sas_phy_enable(hisi_hba, phy_no, 0); |
---|
801 | 1002 | if (phy->identify.device_type == SAS_END_DEVICE) { |
---|
802 | 1003 | txid_auto = hisi_sas_phy_read32(hisi_hba, phy_no, TXID_AUTO); |
---|
803 | 1004 | hisi_sas_phy_write32(hisi_hba, phy_no, TXID_AUTO, |
---|
804 | 1005 | txid_auto | TX_HARDRST_MSK); |
---|
805 | 1006 | } |
---|
806 | 1007 | msleep(100); |
---|
807 | | - start_phy_v3_hw(hisi_hba, phy_no); |
---|
| 1008 | + hisi_sas_phy_enable(hisi_hba, phy_no, 1); |
---|
808 | 1009 | } |
---|
809 | 1010 | |
---|
810 | 1011 | static enum sas_linkrate phy_get_max_linkrate_v3_hw(void) |
---|
.. | .. |
---|
823 | 1024 | if (!sas_phy->phy->enabled) |
---|
824 | 1025 | continue; |
---|
825 | 1026 | |
---|
826 | | - start_phy_v3_hw(hisi_hba, i); |
---|
| 1027 | + hisi_sas_phy_enable(hisi_hba, i, 1); |
---|
827 | 1028 | } |
---|
828 | 1029 | } |
---|
829 | 1030 | |
---|
.. | .. |
---|
852 | 1053 | bitmap |= BIT(i); |
---|
853 | 1054 | |
---|
854 | 1055 | 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 | 1056 | } |
---|
881 | 1057 | |
---|
882 | 1058 | static void start_delivery_v3_hw(struct hisi_sas_dq *dq) |
---|
.. | .. |
---|
926 | 1102 | |
---|
927 | 1103 | hdr->prd_table_addr = cpu_to_le64(hisi_sas_sge_addr_dma(slot)); |
---|
928 | 1104 | |
---|
929 | | - hdr->sg_len = cpu_to_le32(n_elem << CMD_HDR_DATA_SGL_LEN_OFF); |
---|
| 1105 | + hdr->sg_len |= cpu_to_le32(n_elem << CMD_HDR_DATA_SGL_LEN_OFF); |
---|
| 1106 | +} |
---|
| 1107 | + |
---|
| 1108 | +static void prep_prd_sge_dif_v3_hw(struct hisi_hba *hisi_hba, |
---|
| 1109 | + struct hisi_sas_slot *slot, |
---|
| 1110 | + struct hisi_sas_cmd_hdr *hdr, |
---|
| 1111 | + struct scatterlist *scatter, |
---|
| 1112 | + int n_elem) |
---|
| 1113 | +{ |
---|
| 1114 | + struct hisi_sas_sge_dif_page *sge_dif_page; |
---|
| 1115 | + struct scatterlist *sg; |
---|
| 1116 | + int i; |
---|
| 1117 | + |
---|
| 1118 | + sge_dif_page = hisi_sas_sge_dif_addr_mem(slot); |
---|
| 1119 | + |
---|
| 1120 | + for_each_sg(scatter, sg, n_elem, i) { |
---|
| 1121 | + struct hisi_sas_sge *entry = &sge_dif_page->sge[i]; |
---|
| 1122 | + |
---|
| 1123 | + entry->addr = cpu_to_le64(sg_dma_address(sg)); |
---|
| 1124 | + entry->page_ctrl_0 = 0; |
---|
| 1125 | + entry->page_ctrl_1 = 0; |
---|
| 1126 | + entry->data_len = cpu_to_le32(sg_dma_len(sg)); |
---|
| 1127 | + entry->data_off = 0; |
---|
| 1128 | + } |
---|
| 1129 | + |
---|
| 1130 | + hdr->dif_prd_table_addr = |
---|
| 1131 | + cpu_to_le64(hisi_sas_sge_dif_addr_dma(slot)); |
---|
| 1132 | + |
---|
| 1133 | + hdr->sg_len |= cpu_to_le32(n_elem << CMD_HDR_DIF_SGL_LEN_OFF); |
---|
| 1134 | +} |
---|
| 1135 | + |
---|
| 1136 | +static u32 get_prot_chk_msk_v3_hw(struct scsi_cmnd *scsi_cmnd) |
---|
| 1137 | +{ |
---|
| 1138 | + unsigned char prot_flags = scsi_cmnd->prot_flags; |
---|
| 1139 | + |
---|
| 1140 | + if (prot_flags & SCSI_PROT_REF_CHECK) |
---|
| 1141 | + return T10_CHK_APP_TAG_MSK; |
---|
| 1142 | + return T10_CHK_REF_TAG_MSK | T10_CHK_APP_TAG_MSK; |
---|
| 1143 | +} |
---|
| 1144 | + |
---|
| 1145 | +static void fill_prot_v3_hw(struct scsi_cmnd *scsi_cmnd, |
---|
| 1146 | + struct hisi_sas_protect_iu_v3_hw *prot) |
---|
| 1147 | +{ |
---|
| 1148 | + unsigned char prot_op = scsi_get_prot_op(scsi_cmnd); |
---|
| 1149 | + unsigned int interval = scsi_prot_interval(scsi_cmnd); |
---|
| 1150 | + u32 lbrt_chk_val = t10_pi_ref_tag(scsi_cmnd->request); |
---|
| 1151 | + |
---|
| 1152 | + switch (prot_op) { |
---|
| 1153 | + case SCSI_PROT_READ_INSERT: |
---|
| 1154 | + prot->dw0 |= T10_INSRT_EN_MSK; |
---|
| 1155 | + prot->lbrtgv = lbrt_chk_val; |
---|
| 1156 | + break; |
---|
| 1157 | + case SCSI_PROT_READ_STRIP: |
---|
| 1158 | + prot->dw0 |= (T10_RMV_EN_MSK | 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_READ_PASS: |
---|
| 1163 | + prot->dw0 |= T10_CHK_EN_MSK; |
---|
| 1164 | + prot->lbrtcv = lbrt_chk_val; |
---|
| 1165 | + prot->dw4 |= get_prot_chk_msk_v3_hw(scsi_cmnd); |
---|
| 1166 | + break; |
---|
| 1167 | + case SCSI_PROT_WRITE_INSERT: |
---|
| 1168 | + prot->dw0 |= T10_INSRT_EN_MSK; |
---|
| 1169 | + prot->lbrtgv = lbrt_chk_val; |
---|
| 1170 | + break; |
---|
| 1171 | + case SCSI_PROT_WRITE_STRIP: |
---|
| 1172 | + prot->dw0 |= (T10_RMV_EN_MSK | T10_CHK_EN_MSK); |
---|
| 1173 | + prot->lbrtcv = lbrt_chk_val; |
---|
| 1174 | + break; |
---|
| 1175 | + case SCSI_PROT_WRITE_PASS: |
---|
| 1176 | + prot->dw0 |= T10_CHK_EN_MSK; |
---|
| 1177 | + prot->lbrtcv = lbrt_chk_val; |
---|
| 1178 | + prot->dw4 |= get_prot_chk_msk_v3_hw(scsi_cmnd); |
---|
| 1179 | + break; |
---|
| 1180 | + default: |
---|
| 1181 | + WARN(1, "prot_op(0x%x) is not valid\n", prot_op); |
---|
| 1182 | + break; |
---|
| 1183 | + } |
---|
| 1184 | + |
---|
| 1185 | + switch (interval) { |
---|
| 1186 | + case 512: |
---|
| 1187 | + break; |
---|
| 1188 | + case 4096: |
---|
| 1189 | + prot->dw0 |= (0x1 << USR_DATA_BLOCK_SZ_OFF); |
---|
| 1190 | + break; |
---|
| 1191 | + case 520: |
---|
| 1192 | + prot->dw0 |= (0x2 << USR_DATA_BLOCK_SZ_OFF); |
---|
| 1193 | + break; |
---|
| 1194 | + default: |
---|
| 1195 | + WARN(1, "protection interval (0x%x) invalid\n", |
---|
| 1196 | + interval); |
---|
| 1197 | + break; |
---|
| 1198 | + } |
---|
| 1199 | + |
---|
| 1200 | + prot->dw0 |= INCR_LBRT_MSK; |
---|
930 | 1201 | } |
---|
931 | 1202 | |
---|
932 | 1203 | static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba, |
---|
.. | .. |
---|
941 | 1212 | struct scsi_cmnd *scsi_cmnd = ssp_task->cmd; |
---|
942 | 1213 | struct hisi_sas_tmf_task *tmf = slot->tmf; |
---|
943 | 1214 | int has_data = 0, priority = !!tmf; |
---|
| 1215 | + unsigned char prot_op; |
---|
944 | 1216 | u8 *buf_cmd; |
---|
945 | | - u32 dw1 = 0, dw2 = 0; |
---|
| 1217 | + u32 dw1 = 0, dw2 = 0, len = 0; |
---|
946 | 1218 | |
---|
947 | 1219 | hdr->dw0 = cpu_to_le32((1 << CMD_HDR_RESP_REPORT_OFF) | |
---|
948 | 1220 | (2 << CMD_HDR_TLR_CTRL_OFF) | |
---|
.. | .. |
---|
955 | 1227 | dw1 |= 2 << CMD_HDR_FRAME_TYPE_OFF; |
---|
956 | 1228 | dw1 |= DIR_NO_DATA << CMD_HDR_DIR_OFF; |
---|
957 | 1229 | } else { |
---|
| 1230 | + prot_op = scsi_get_prot_op(scsi_cmnd); |
---|
958 | 1231 | dw1 |= 1 << CMD_HDR_FRAME_TYPE_OFF; |
---|
959 | 1232 | switch (scsi_cmnd->sc_data_direction) { |
---|
960 | 1233 | case DMA_TO_DEVICE: |
---|
.. | .. |
---|
972 | 1245 | |
---|
973 | 1246 | /* map itct entry */ |
---|
974 | 1247 | dw1 |= sas_dev->device_id << CMD_HDR_DEV_ID_OFF; |
---|
975 | | - hdr->dw1 = cpu_to_le32(dw1); |
---|
976 | 1248 | |
---|
977 | 1249 | dw2 = (((sizeof(struct ssp_command_iu) + sizeof(struct ssp_frame_hdr) |
---|
978 | 1250 | + 3) / 4) << CMD_HDR_CFL_OFF) | |
---|
.. | .. |
---|
981 | 1253 | hdr->dw2 = cpu_to_le32(dw2); |
---|
982 | 1254 | hdr->transfer_tags = cpu_to_le32(slot->idx); |
---|
983 | 1255 | |
---|
984 | | - if (has_data) |
---|
| 1256 | + if (has_data) { |
---|
985 | 1257 | prep_prd_sge_v3_hw(hisi_hba, slot, hdr, task->scatter, |
---|
986 | | - slot->n_elem); |
---|
| 1258 | + slot->n_elem); |
---|
987 | 1259 | |
---|
988 | | - hdr->data_transfer_len = cpu_to_le32(task->total_xfer_len); |
---|
| 1260 | + if (scsi_prot_sg_count(scsi_cmnd)) |
---|
| 1261 | + prep_prd_sge_dif_v3_hw(hisi_hba, slot, hdr, |
---|
| 1262 | + scsi_prot_sglist(scsi_cmnd), |
---|
| 1263 | + slot->n_elem_dif); |
---|
| 1264 | + } |
---|
| 1265 | + |
---|
989 | 1266 | hdr->cmd_table_addr = cpu_to_le64(hisi_sas_cmd_hdr_addr_dma(slot)); |
---|
990 | 1267 | hdr->sts_buffer_addr = cpu_to_le64(hisi_sas_status_buf_addr_dma(slot)); |
---|
991 | 1268 | |
---|
.. | .. |
---|
1010 | 1287 | break; |
---|
1011 | 1288 | } |
---|
1012 | 1289 | } |
---|
| 1290 | + |
---|
| 1291 | + if (has_data && (prot_op != SCSI_PROT_NORMAL)) { |
---|
| 1292 | + struct hisi_sas_protect_iu_v3_hw prot; |
---|
| 1293 | + u8 *buf_cmd_prot; |
---|
| 1294 | + |
---|
| 1295 | + hdr->dw7 |= cpu_to_le32(1 << CMD_HDR_ADDR_MODE_SEL_OFF); |
---|
| 1296 | + dw1 |= CMD_HDR_PIR_MSK; |
---|
| 1297 | + buf_cmd_prot = hisi_sas_cmd_hdr_addr_mem(slot) + |
---|
| 1298 | + sizeof(struct ssp_frame_hdr) + |
---|
| 1299 | + sizeof(struct ssp_command_iu); |
---|
| 1300 | + |
---|
| 1301 | + memset(&prot, 0, sizeof(struct hisi_sas_protect_iu_v3_hw)); |
---|
| 1302 | + fill_prot_v3_hw(scsi_cmnd, &prot); |
---|
| 1303 | + memcpy(buf_cmd_prot, &prot, |
---|
| 1304 | + sizeof(struct hisi_sas_protect_iu_v3_hw)); |
---|
| 1305 | + /* |
---|
| 1306 | + * For READ, we need length of info read to memory, while for |
---|
| 1307 | + * WRITE we need length of data written to the disk. |
---|
| 1308 | + */ |
---|
| 1309 | + if (prot_op == SCSI_PROT_WRITE_INSERT || |
---|
| 1310 | + prot_op == SCSI_PROT_READ_INSERT || |
---|
| 1311 | + prot_op == SCSI_PROT_WRITE_PASS || |
---|
| 1312 | + prot_op == SCSI_PROT_READ_PASS) { |
---|
| 1313 | + unsigned int interval = scsi_prot_interval(scsi_cmnd); |
---|
| 1314 | + unsigned int ilog2_interval = ilog2(interval); |
---|
| 1315 | + |
---|
| 1316 | + len = (task->total_xfer_len >> ilog2_interval) * 8; |
---|
| 1317 | + } |
---|
| 1318 | + } |
---|
| 1319 | + |
---|
| 1320 | + hdr->dw1 = cpu_to_le32(dw1); |
---|
| 1321 | + |
---|
| 1322 | + hdr->data_transfer_len = cpu_to_le32(task->total_xfer_len + len); |
---|
1013 | 1323 | } |
---|
1014 | 1324 | |
---|
1015 | 1325 | static void prep_smp_v3_hw(struct hisi_hba *hisi_hba, |
---|
.. | .. |
---|
1049 | 1359 | |
---|
1050 | 1360 | hdr->cmd_table_addr = cpu_to_le64(req_dma_addr); |
---|
1051 | 1361 | hdr->sts_buffer_addr = cpu_to_le64(hisi_sas_status_buf_addr_dma(slot)); |
---|
1052 | | - |
---|
1053 | 1362 | } |
---|
1054 | 1363 | |
---|
1055 | 1364 | static void prep_ata_v3_hw(struct hisi_hba *hisi_hba, |
---|
.. | .. |
---|
1067 | 1376 | u32 dw1 = 0, dw2 = 0; |
---|
1068 | 1377 | |
---|
1069 | 1378 | hdr->dw0 = cpu_to_le32(port->id << CMD_HDR_PORT_OFF); |
---|
1070 | | - if (parent_dev && DEV_IS_EXPANDER(parent_dev->dev_type)) |
---|
| 1379 | + if (parent_dev && dev_is_expander(parent_dev->dev_type)) |
---|
1071 | 1380 | hdr->dw0 |= cpu_to_le32(3 << CMD_HDR_CMD_OFF); |
---|
1072 | 1381 | else |
---|
1073 | | - hdr->dw0 |= cpu_to_le32(4 << CMD_HDR_CMD_OFF); |
---|
| 1382 | + hdr->dw0 |= cpu_to_le32(4U << CMD_HDR_CMD_OFF); |
---|
1074 | 1383 | |
---|
1075 | 1384 | switch (task->data_dir) { |
---|
1076 | 1385 | case DMA_TO_DEVICE: |
---|
.. | .. |
---|
1100 | 1409 | hdr->dw1 = cpu_to_le32(dw1); |
---|
1101 | 1410 | |
---|
1102 | 1411 | /* dw2 */ |
---|
1103 | | - if (task->ata_task.use_ncq && hisi_sas_get_ncq_tag(task, &hdr_tag)) { |
---|
| 1412 | + if (task->ata_task.use_ncq) { |
---|
| 1413 | + struct ata_queued_cmd *qc = task->uldd_task; |
---|
| 1414 | + |
---|
| 1415 | + hdr_tag = qc->tag; |
---|
1104 | 1416 | task->ata_task.fis.sector_count |= (u8) (hdr_tag << 3); |
---|
1105 | 1417 | dw2 |= hdr_tag << CMD_HDR_NCQ_TAG_OFF; |
---|
1106 | 1418 | } |
---|
.. | .. |
---|
1138 | 1450 | struct hisi_sas_port *port = slot->port; |
---|
1139 | 1451 | |
---|
1140 | 1452 | /* dw0 */ |
---|
1141 | | - hdr->dw0 = cpu_to_le32((5 << CMD_HDR_CMD_OFF) | /*abort*/ |
---|
| 1453 | + hdr->dw0 = cpu_to_le32((5U << CMD_HDR_CMD_OFF) | /*abort*/ |
---|
1142 | 1454 | (port->id << CMD_HDR_PORT_OFF) | |
---|
1143 | 1455 | (dev_is_sata(dev) |
---|
1144 | 1456 | << CMD_HDR_ABORT_DEVICE_TYPE_OFF) | |
---|
.. | .. |
---|
1152 | 1464 | /* dw7 */ |
---|
1153 | 1465 | hdr->dw7 = cpu_to_le32(tag_to_abort << CMD_HDR_ABORT_IPTT_OFF); |
---|
1154 | 1466 | hdr->transfer_tags = cpu_to_le32(slot->idx); |
---|
1155 | | - |
---|
1156 | 1467 | } |
---|
1157 | 1468 | |
---|
1158 | 1469 | static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba) |
---|
1159 | 1470 | { |
---|
1160 | | - int i, res; |
---|
| 1471 | + int i; |
---|
| 1472 | + irqreturn_t res; |
---|
1161 | 1473 | u32 context, port_id, link_rate; |
---|
1162 | 1474 | struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; |
---|
1163 | 1475 | struct asd_sas_phy *sas_phy = &phy->sas_phy; |
---|
1164 | 1476 | struct device *dev = hisi_hba->dev; |
---|
1165 | 1477 | unsigned long flags; |
---|
1166 | 1478 | |
---|
| 1479 | + del_timer(&phy->timer); |
---|
1167 | 1480 | hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 1); |
---|
1168 | 1481 | |
---|
1169 | 1482 | port_id = hisi_sas_read32(hisi_hba, PHY_PORT_NUM_MA); |
---|
.. | .. |
---|
1185 | 1498 | struct hisi_sas_initial_fis *initial_fis; |
---|
1186 | 1499 | struct dev_to_host_fis *fis; |
---|
1187 | 1500 | u8 attached_sas_addr[SAS_ADDR_SIZE] = {0}; |
---|
| 1501 | + struct Scsi_Host *shost = hisi_hba->shost; |
---|
1188 | 1502 | |
---|
1189 | 1503 | dev_info(dev, "phyup: phy%d link_rate=%d(sata)\n", phy_no, link_rate); |
---|
1190 | 1504 | initial_fis = &hisi_hba->initial_fis[phy_no]; |
---|
.. | .. |
---|
1201 | 1515 | |
---|
1202 | 1516 | sas_phy->oob_mode = SATA_OOB_MODE; |
---|
1203 | 1517 | attached_sas_addr[0] = 0x50; |
---|
| 1518 | + attached_sas_addr[6] = shost->host_no; |
---|
1204 | 1519 | attached_sas_addr[7] = phy_no; |
---|
1205 | 1520 | memcpy(sas_phy->attached_sas_addr, |
---|
1206 | 1521 | attached_sas_addr, |
---|
.. | .. |
---|
1257 | 1572 | |
---|
1258 | 1573 | static irqreturn_t phy_down_v3_hw(int phy_no, struct hisi_hba *hisi_hba) |
---|
1259 | 1574 | { |
---|
| 1575 | + struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; |
---|
1260 | 1576 | u32 phy_state, sl_ctrl, txid_auto; |
---|
1261 | 1577 | struct device *dev = hisi_hba->dev; |
---|
1262 | 1578 | |
---|
| 1579 | + atomic_inc(&phy->down_cnt); |
---|
| 1580 | + |
---|
| 1581 | + del_timer(&phy->timer); |
---|
1263 | 1582 | hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_NOT_RDY_MSK, 1); |
---|
1264 | 1583 | |
---|
1265 | 1584 | phy_state = hisi_sas_read32(hisi_hba, PHY_STATE); |
---|
.. | .. |
---|
1284 | 1603 | { |
---|
1285 | 1604 | struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; |
---|
1286 | 1605 | struct asd_sas_phy *sas_phy = &phy->sas_phy; |
---|
1287 | | - struct sas_ha_struct *sas_ha = &hisi_hba->sha; |
---|
1288 | 1606 | u32 bcast_status; |
---|
1289 | 1607 | |
---|
1290 | 1608 | hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 1); |
---|
1291 | 1609 | bcast_status = hisi_sas_phy_read32(hisi_hba, phy_no, RX_PRIMS_STATUS); |
---|
1292 | 1610 | if ((bcast_status & RX_BCAST_CHG_MSK) && |
---|
1293 | 1611 | !test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) |
---|
1294 | | - sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); |
---|
| 1612 | + sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); |
---|
1295 | 1613 | hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, |
---|
1296 | 1614 | CHL_INT0_SL_RX_BCST_ACK_MSK); |
---|
1297 | 1615 | hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 0); |
---|
.. | .. |
---|
1343 | 1661 | |
---|
1344 | 1662 | static const struct hisi_sas_hw_error port_axi_error[] = { |
---|
1345 | 1663 | { |
---|
| 1664 | + .irq_msk = BIT(CHL_INT1_DMAC_TX_ECC_MB_ERR_OFF), |
---|
| 1665 | + .msg = "dmac_tx_ecc_bad_err", |
---|
| 1666 | + }, |
---|
| 1667 | + { |
---|
| 1668 | + .irq_msk = BIT(CHL_INT1_DMAC_RX_ECC_MB_ERR_OFF), |
---|
| 1669 | + .msg = "dmac_rx_ecc_bad_err", |
---|
| 1670 | + }, |
---|
| 1671 | + { |
---|
1346 | 1672 | .irq_msk = BIT(CHL_INT1_DMAC_TX_AXI_WR_ERR_OFF), |
---|
1347 | 1673 | .msg = "dma_tx_axi_wr_err", |
---|
1348 | 1674 | }, |
---|
.. | .. |
---|
1357 | 1683 | { |
---|
1358 | 1684 | .irq_msk = BIT(CHL_INT1_DMAC_RX_AXI_RD_ERR_OFF), |
---|
1359 | 1685 | .msg = "dma_rx_axi_rd_err", |
---|
| 1686 | + }, |
---|
| 1687 | + { |
---|
| 1688 | + .irq_msk = BIT(CHL_INT1_DMAC_TX_FIFO_ERR_OFF), |
---|
| 1689 | + .msg = "dma_tx_fifo_err", |
---|
| 1690 | + }, |
---|
| 1691 | + { |
---|
| 1692 | + .irq_msk = BIT(CHL_INT1_DMAC_RX_FIFO_ERR_OFF), |
---|
| 1693 | + .msg = "dma_rx_fifo_err", |
---|
| 1694 | + }, |
---|
| 1695 | + { |
---|
| 1696 | + .irq_msk = BIT(CHL_INT1_DMAC_TX_AXI_RUSER_ERR_OFF), |
---|
| 1697 | + .msg = "dma_tx_axi_ruser_err", |
---|
| 1698 | + }, |
---|
| 1699 | + { |
---|
| 1700 | + .irq_msk = BIT(CHL_INT1_DMAC_RX_AXI_RUSER_ERR_OFF), |
---|
| 1701 | + .msg = "dma_rx_axi_ruser_err", |
---|
1360 | 1702 | }, |
---|
1361 | 1703 | }; |
---|
1362 | 1704 | |
---|
.. | .. |
---|
1385 | 1727 | hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT1, irq_value); |
---|
1386 | 1728 | } |
---|
1387 | 1729 | |
---|
| 1730 | +static void phy_get_events_v3_hw(struct hisi_hba *hisi_hba, int phy_no) |
---|
| 1731 | +{ |
---|
| 1732 | + struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; |
---|
| 1733 | + struct asd_sas_phy *sas_phy = &phy->sas_phy; |
---|
| 1734 | + struct sas_phy *sphy = sas_phy->phy; |
---|
| 1735 | + unsigned long flags; |
---|
| 1736 | + u32 reg_value; |
---|
| 1737 | + |
---|
| 1738 | + spin_lock_irqsave(&phy->lock, flags); |
---|
| 1739 | + |
---|
| 1740 | + /* loss dword sync */ |
---|
| 1741 | + reg_value = hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_DWS_LOST); |
---|
| 1742 | + sphy->loss_of_dword_sync_count += reg_value; |
---|
| 1743 | + |
---|
| 1744 | + /* phy reset problem */ |
---|
| 1745 | + reg_value = hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_RESET_PROB); |
---|
| 1746 | + sphy->phy_reset_problem_count += reg_value; |
---|
| 1747 | + |
---|
| 1748 | + /* invalid dword */ |
---|
| 1749 | + reg_value = hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_INVLD_DW); |
---|
| 1750 | + sphy->invalid_dword_count += reg_value; |
---|
| 1751 | + |
---|
| 1752 | + /* disparity err */ |
---|
| 1753 | + reg_value = hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_DISP_ERR); |
---|
| 1754 | + sphy->running_disparity_error_count += reg_value; |
---|
| 1755 | + |
---|
| 1756 | + /* code violation error */ |
---|
| 1757 | + reg_value = hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_CODE_ERR); |
---|
| 1758 | + phy->code_violation_err_count += reg_value; |
---|
| 1759 | + |
---|
| 1760 | + spin_unlock_irqrestore(&phy->lock, flags); |
---|
| 1761 | +} |
---|
| 1762 | + |
---|
1388 | 1763 | static void handle_chl_int2_v3_hw(struct hisi_hba *hisi_hba, int phy_no) |
---|
1389 | 1764 | { |
---|
1390 | 1765 | u32 irq_msk = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT2_MSK); |
---|
.. | .. |
---|
1392 | 1767 | struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; |
---|
1393 | 1768 | struct pci_dev *pci_dev = hisi_hba->pci_dev; |
---|
1394 | 1769 | struct device *dev = hisi_hba->dev; |
---|
| 1770 | + static const u32 msk = BIT(CHL_INT2_RX_DISP_ERR_OFF) | |
---|
| 1771 | + BIT(CHL_INT2_RX_CODE_ERR_OFF) | |
---|
| 1772 | + BIT(CHL_INT2_RX_INVLD_DW_OFF); |
---|
1395 | 1773 | |
---|
1396 | 1774 | irq_value &= ~irq_msk; |
---|
1397 | 1775 | if (!irq_value) |
---|
.. | .. |
---|
1412 | 1790 | hisi_sas_notify_phy_event(phy, HISI_PHYE_LINK_RESET); |
---|
1413 | 1791 | } |
---|
1414 | 1792 | |
---|
| 1793 | + if (pci_dev->revision > 0x20 && (irq_value & msk)) { |
---|
| 1794 | + struct asd_sas_phy *sas_phy = &phy->sas_phy; |
---|
| 1795 | + struct sas_phy *sphy = sas_phy->phy; |
---|
| 1796 | + |
---|
| 1797 | + phy_get_events_v3_hw(hisi_hba, phy_no); |
---|
| 1798 | + |
---|
| 1799 | + if (irq_value & BIT(CHL_INT2_RX_INVLD_DW_OFF)) |
---|
| 1800 | + dev_info(dev, "phy%d invalid dword cnt: %u\n", phy_no, |
---|
| 1801 | + sphy->invalid_dword_count); |
---|
| 1802 | + |
---|
| 1803 | + if (irq_value & BIT(CHL_INT2_RX_CODE_ERR_OFF)) |
---|
| 1804 | + dev_info(dev, "phy%d code violation cnt: %u\n", phy_no, |
---|
| 1805 | + phy->code_violation_err_count); |
---|
| 1806 | + |
---|
| 1807 | + if (irq_value & BIT(CHL_INT2_RX_DISP_ERR_OFF)) |
---|
| 1808 | + dev_info(dev, "phy%d disparity error cnt: %u\n", phy_no, |
---|
| 1809 | + sphy->running_disparity_error_count); |
---|
| 1810 | + } |
---|
| 1811 | + |
---|
1415 | 1812 | if ((irq_value & BIT(CHL_INT2_RX_INVLD_DW_OFF)) && |
---|
1416 | 1813 | (pci_dev->revision == 0x20)) { |
---|
1417 | 1814 | u32 reg_value; |
---|
.. | .. |
---|
1428 | 1825 | hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2, irq_value); |
---|
1429 | 1826 | } |
---|
1430 | 1827 | |
---|
| 1828 | +static void handle_chl_int0_v3_hw(struct hisi_hba *hisi_hba, int phy_no) |
---|
| 1829 | +{ |
---|
| 1830 | + u32 irq_value0 = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT0); |
---|
| 1831 | + |
---|
| 1832 | + if (irq_value0 & CHL_INT0_PHY_RDY_MSK) |
---|
| 1833 | + hisi_sas_phy_oob_ready(hisi_hba, phy_no); |
---|
| 1834 | + |
---|
| 1835 | + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, |
---|
| 1836 | + irq_value0 & (~CHL_INT0_SL_RX_BCST_ACK_MSK) |
---|
| 1837 | + & (~CHL_INT0_SL_PHY_ENABLE_MSK) |
---|
| 1838 | + & (~CHL_INT0_NOT_RDY_MSK)); |
---|
| 1839 | +} |
---|
| 1840 | + |
---|
1431 | 1841 | static irqreturn_t int_chnl_int_v3_hw(int irq_no, void *p) |
---|
1432 | 1842 | { |
---|
1433 | 1843 | struct hisi_hba *hisi_hba = p; |
---|
.. | .. |
---|
1435 | 1845 | int phy_no = 0; |
---|
1436 | 1846 | |
---|
1437 | 1847 | irq_msk = hisi_sas_read32(hisi_hba, CHNL_INT_STATUS) |
---|
1438 | | - & 0xeeeeeeee; |
---|
| 1848 | + & CHNL_INT_STS_MSK; |
---|
1439 | 1849 | |
---|
1440 | 1850 | while (irq_msk) { |
---|
1441 | | - u32 irq_value0 = hisi_sas_phy_read32(hisi_hba, phy_no, |
---|
1442 | | - CHL_INT0); |
---|
| 1851 | + if (irq_msk & (CHNL_INT_STS_INT0_MSK << (phy_no * CHNL_WIDTH))) |
---|
| 1852 | + handle_chl_int0_v3_hw(hisi_hba, phy_no); |
---|
1443 | 1853 | |
---|
1444 | | - if (irq_msk & (4 << (phy_no * 4))) |
---|
| 1854 | + if (irq_msk & (CHNL_INT_STS_INT1_MSK << (phy_no * CHNL_WIDTH))) |
---|
1445 | 1855 | handle_chl_int1_v3_hw(hisi_hba, phy_no); |
---|
1446 | 1856 | |
---|
1447 | | - if (irq_msk & (8 << (phy_no * 4))) |
---|
| 1857 | + if (irq_msk & (CHNL_INT_STS_INT2_MSK << (phy_no * CHNL_WIDTH))) |
---|
1448 | 1858 | handle_chl_int2_v3_hw(hisi_hba, phy_no); |
---|
1449 | 1859 | |
---|
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)); |
---|
| 1860 | + irq_msk &= ~(CHNL_INT_STS_PHY_MSK << (phy_no * CHNL_WIDTH)); |
---|
1458 | 1861 | phy_no++; |
---|
1459 | 1862 | } |
---|
1460 | 1863 | |
---|
1461 | 1864 | return IRQ_HANDLED; |
---|
| 1865 | +} |
---|
| 1866 | + |
---|
| 1867 | +static const struct hisi_sas_hw_error multi_bit_ecc_errors[] = { |
---|
| 1868 | + { |
---|
| 1869 | + .irq_msk = BIT(SAS_ECC_INTR_DQE_ECC_MB_OFF), |
---|
| 1870 | + .msk = HGC_DQE_ECC_MB_ADDR_MSK, |
---|
| 1871 | + .shift = HGC_DQE_ECC_MB_ADDR_OFF, |
---|
| 1872 | + .msg = "hgc_dqe_eccbad_intr", |
---|
| 1873 | + .reg = HGC_DQE_ECC_ADDR, |
---|
| 1874 | + }, |
---|
| 1875 | + { |
---|
| 1876 | + .irq_msk = BIT(SAS_ECC_INTR_IOST_ECC_MB_OFF), |
---|
| 1877 | + .msk = HGC_IOST_ECC_MB_ADDR_MSK, |
---|
| 1878 | + .shift = HGC_IOST_ECC_MB_ADDR_OFF, |
---|
| 1879 | + .msg = "hgc_iost_eccbad_intr", |
---|
| 1880 | + .reg = HGC_IOST_ECC_ADDR, |
---|
| 1881 | + }, |
---|
| 1882 | + { |
---|
| 1883 | + .irq_msk = BIT(SAS_ECC_INTR_ITCT_ECC_MB_OFF), |
---|
| 1884 | + .msk = HGC_ITCT_ECC_MB_ADDR_MSK, |
---|
| 1885 | + .shift = HGC_ITCT_ECC_MB_ADDR_OFF, |
---|
| 1886 | + .msg = "hgc_itct_eccbad_intr", |
---|
| 1887 | + .reg = HGC_ITCT_ECC_ADDR, |
---|
| 1888 | + }, |
---|
| 1889 | + { |
---|
| 1890 | + .irq_msk = BIT(SAS_ECC_INTR_IOSTLIST_ECC_MB_OFF), |
---|
| 1891 | + .msk = HGC_LM_DFX_STATUS2_IOSTLIST_MSK, |
---|
| 1892 | + .shift = HGC_LM_DFX_STATUS2_IOSTLIST_OFF, |
---|
| 1893 | + .msg = "hgc_iostl_eccbad_intr", |
---|
| 1894 | + .reg = HGC_LM_DFX_STATUS2, |
---|
| 1895 | + }, |
---|
| 1896 | + { |
---|
| 1897 | + .irq_msk = BIT(SAS_ECC_INTR_ITCTLIST_ECC_MB_OFF), |
---|
| 1898 | + .msk = HGC_LM_DFX_STATUS2_ITCTLIST_MSK, |
---|
| 1899 | + .shift = HGC_LM_DFX_STATUS2_ITCTLIST_OFF, |
---|
| 1900 | + .msg = "hgc_itctl_eccbad_intr", |
---|
| 1901 | + .reg = HGC_LM_DFX_STATUS2, |
---|
| 1902 | + }, |
---|
| 1903 | + { |
---|
| 1904 | + .irq_msk = BIT(SAS_ECC_INTR_CQE_ECC_MB_OFF), |
---|
| 1905 | + .msk = HGC_CQE_ECC_MB_ADDR_MSK, |
---|
| 1906 | + .shift = HGC_CQE_ECC_MB_ADDR_OFF, |
---|
| 1907 | + .msg = "hgc_cqe_eccbad_intr", |
---|
| 1908 | + .reg = HGC_CQE_ECC_ADDR, |
---|
| 1909 | + }, |
---|
| 1910 | + { |
---|
| 1911 | + .irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM0_ECC_MB_OFF), |
---|
| 1912 | + .msk = HGC_RXM_DFX_STATUS14_MEM0_MSK, |
---|
| 1913 | + .shift = HGC_RXM_DFX_STATUS14_MEM0_OFF, |
---|
| 1914 | + .msg = "rxm_mem0_eccbad_intr", |
---|
| 1915 | + .reg = HGC_RXM_DFX_STATUS14, |
---|
| 1916 | + }, |
---|
| 1917 | + { |
---|
| 1918 | + .irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM1_ECC_MB_OFF), |
---|
| 1919 | + .msk = HGC_RXM_DFX_STATUS14_MEM1_MSK, |
---|
| 1920 | + .shift = HGC_RXM_DFX_STATUS14_MEM1_OFF, |
---|
| 1921 | + .msg = "rxm_mem1_eccbad_intr", |
---|
| 1922 | + .reg = HGC_RXM_DFX_STATUS14, |
---|
| 1923 | + }, |
---|
| 1924 | + { |
---|
| 1925 | + .irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM2_ECC_MB_OFF), |
---|
| 1926 | + .msk = HGC_RXM_DFX_STATUS14_MEM2_MSK, |
---|
| 1927 | + .shift = HGC_RXM_DFX_STATUS14_MEM2_OFF, |
---|
| 1928 | + .msg = "rxm_mem2_eccbad_intr", |
---|
| 1929 | + .reg = HGC_RXM_DFX_STATUS14, |
---|
| 1930 | + }, |
---|
| 1931 | + { |
---|
| 1932 | + .irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM3_ECC_MB_OFF), |
---|
| 1933 | + .msk = HGC_RXM_DFX_STATUS15_MEM3_MSK, |
---|
| 1934 | + .shift = HGC_RXM_DFX_STATUS15_MEM3_OFF, |
---|
| 1935 | + .msg = "rxm_mem3_eccbad_intr", |
---|
| 1936 | + .reg = HGC_RXM_DFX_STATUS15, |
---|
| 1937 | + }, |
---|
| 1938 | + { |
---|
| 1939 | + .irq_msk = BIT(SAS_ECC_INTR_OOO_RAM_ECC_MB_OFF), |
---|
| 1940 | + .msk = AM_ROB_ECC_ERR_ADDR_MSK, |
---|
| 1941 | + .shift = AM_ROB_ECC_ERR_ADDR_OFF, |
---|
| 1942 | + .msg = "ooo_ram_eccbad_intr", |
---|
| 1943 | + .reg = AM_ROB_ECC_ERR_ADDR, |
---|
| 1944 | + }, |
---|
| 1945 | +}; |
---|
| 1946 | + |
---|
| 1947 | +static void multi_bit_ecc_error_process_v3_hw(struct hisi_hba *hisi_hba, |
---|
| 1948 | + u32 irq_value) |
---|
| 1949 | +{ |
---|
| 1950 | + struct device *dev = hisi_hba->dev; |
---|
| 1951 | + const struct hisi_sas_hw_error *ecc_error; |
---|
| 1952 | + u32 val; |
---|
| 1953 | + int i; |
---|
| 1954 | + |
---|
| 1955 | + for (i = 0; i < ARRAY_SIZE(multi_bit_ecc_errors); i++) { |
---|
| 1956 | + ecc_error = &multi_bit_ecc_errors[i]; |
---|
| 1957 | + if (irq_value & ecc_error->irq_msk) { |
---|
| 1958 | + val = hisi_sas_read32(hisi_hba, ecc_error->reg); |
---|
| 1959 | + val &= ecc_error->msk; |
---|
| 1960 | + val >>= ecc_error->shift; |
---|
| 1961 | + dev_err(dev, "%s (0x%x) found: mem addr is 0x%08X\n", |
---|
| 1962 | + ecc_error->msg, irq_value, val); |
---|
| 1963 | + queue_work(hisi_hba->wq, &hisi_hba->rst_work); |
---|
| 1964 | + } |
---|
| 1965 | + } |
---|
| 1966 | +} |
---|
| 1967 | + |
---|
| 1968 | +static void fatal_ecc_int_v3_hw(struct hisi_hba *hisi_hba) |
---|
| 1969 | +{ |
---|
| 1970 | + u32 irq_value, irq_msk; |
---|
| 1971 | + |
---|
| 1972 | + irq_msk = hisi_sas_read32(hisi_hba, SAS_ECC_INTR_MSK); |
---|
| 1973 | + hisi_sas_write32(hisi_hba, SAS_ECC_INTR_MSK, 0xffffffff); |
---|
| 1974 | + |
---|
| 1975 | + irq_value = hisi_sas_read32(hisi_hba, SAS_ECC_INTR); |
---|
| 1976 | + if (irq_value) |
---|
| 1977 | + multi_bit_ecc_error_process_v3_hw(hisi_hba, irq_value); |
---|
| 1978 | + |
---|
| 1979 | + hisi_sas_write32(hisi_hba, SAS_ECC_INTR, irq_value); |
---|
| 1980 | + hisi_sas_write32(hisi_hba, SAS_ECC_INTR_MSK, irq_msk); |
---|
1462 | 1981 | } |
---|
1463 | 1982 | |
---|
1464 | 1983 | static const struct hisi_sas_hw_error axi_error[] = { |
---|
.. | .. |
---|
1470 | 1989 | { .msk = BIT(5), .msg = "SATA_AXI_R_ERR" }, |
---|
1471 | 1990 | { .msk = BIT(6), .msg = "DQE_AXI_R_ERR" }, |
---|
1472 | 1991 | { .msk = BIT(7), .msg = "CQE_AXI_W_ERR" }, |
---|
1473 | | - {}, |
---|
| 1992 | + {} |
---|
1474 | 1993 | }; |
---|
1475 | 1994 | |
---|
1476 | 1995 | static const struct hisi_sas_hw_error fifo_error[] = { |
---|
.. | .. |
---|
1479 | 1998 | { .msk = BIT(10), .msg = "GETDQE_FIFO" }, |
---|
1480 | 1999 | { .msk = BIT(11), .msg = "CMDP_FIFO" }, |
---|
1481 | 2000 | { .msk = BIT(12), .msg = "AWTCTRL_FIFO" }, |
---|
1482 | | - {}, |
---|
| 2001 | + {} |
---|
1483 | 2002 | }; |
---|
1484 | 2003 | |
---|
1485 | 2004 | static const struct hisi_sas_hw_error fatal_axi_error[] = { |
---|
.. | .. |
---|
1513 | 2032 | .irq_msk = BIT(ENT_INT_SRC3_ABT_OFF), |
---|
1514 | 2033 | .msg = "SAS_HGC_ABT fetch LM list", |
---|
1515 | 2034 | }, |
---|
| 2035 | + { |
---|
| 2036 | + .irq_msk = BIT(ENT_INT_SRC3_DQE_POISON_OFF), |
---|
| 2037 | + .msg = "read dqe poison", |
---|
| 2038 | + }, |
---|
| 2039 | + { |
---|
| 2040 | + .irq_msk = BIT(ENT_INT_SRC3_IOST_POISON_OFF), |
---|
| 2041 | + .msg = "read iost poison", |
---|
| 2042 | + }, |
---|
| 2043 | + { |
---|
| 2044 | + .irq_msk = BIT(ENT_INT_SRC3_ITCT_POISON_OFF), |
---|
| 2045 | + .msg = "read itct poison", |
---|
| 2046 | + }, |
---|
| 2047 | + { |
---|
| 2048 | + .irq_msk = BIT(ENT_INT_SRC3_ITCT_NCQ_POISON_OFF), |
---|
| 2049 | + .msg = "read itct ncq poison", |
---|
| 2050 | + }, |
---|
| 2051 | + |
---|
1516 | 2052 | }; |
---|
1517 | 2053 | |
---|
1518 | 2054 | static irqreturn_t fatal_axi_int_v3_hw(int irq_no, void *p) |
---|
.. | .. |
---|
1565 | 2101 | } |
---|
1566 | 2102 | } |
---|
1567 | 2103 | |
---|
| 2104 | + fatal_ecc_int_v3_hw(hisi_hba); |
---|
| 2105 | + |
---|
1568 | 2106 | if (irq_value & BIT(ENT_INT_SRC3_ITC_INT_OFF)) { |
---|
1569 | 2107 | u32 reg_val = hisi_sas_read32(hisi_hba, ITCT_CLR); |
---|
1570 | 2108 | u32 dev_id = reg_val & ITCT_DEV_MSK; |
---|
.. | .. |
---|
1582 | 2120 | return IRQ_HANDLED; |
---|
1583 | 2121 | } |
---|
1584 | 2122 | |
---|
1585 | | -static void |
---|
| 2123 | +static bool |
---|
1586 | 2124 | slot_err_v3_hw(struct hisi_hba *hisi_hba, struct sas_task *task, |
---|
1587 | 2125 | struct hisi_sas_slot *slot) |
---|
1588 | 2126 | { |
---|
.. | .. |
---|
1593 | 2131 | &complete_queue[slot->cmplt_queue_slot]; |
---|
1594 | 2132 | struct hisi_sas_err_record_v3 *record = |
---|
1595 | 2133 | 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; |
---|
| 2134 | + u32 dma_rx_err_type = le32_to_cpu(record->dma_rx_err_type); |
---|
| 2135 | + u32 trans_tx_fail_type = le32_to_cpu(record->trans_tx_fail_type); |
---|
| 2136 | + u16 sipc_rx_err_type = le16_to_cpu(record->sipc_rx_err_type); |
---|
| 2137 | + u32 dw3 = le32_to_cpu(complete_hdr->dw3); |
---|
| 2138 | + u32 dw0 = le32_to_cpu(complete_hdr->dw0); |
---|
1598 | 2139 | |
---|
1599 | 2140 | switch (task->task_proto) { |
---|
1600 | 2141 | case SAS_PROTOCOL_SSP: |
---|
1601 | 2142 | if (dma_rx_err_type & RX_DATA_LEN_UNDERFLOW_MSK) { |
---|
| 2143 | + /* |
---|
| 2144 | + * If returned response frame is incorrect because of data underflow, |
---|
| 2145 | + * but I/O information has been written to the host memory, we examine |
---|
| 2146 | + * response IU. |
---|
| 2147 | + */ |
---|
| 2148 | + if (!(dw0 & CMPLT_HDR_RSPNS_GOOD_MSK) && |
---|
| 2149 | + (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK)) |
---|
| 2150 | + return false; |
---|
| 2151 | + |
---|
1602 | 2152 | ts->residual = trans_tx_fail_type; |
---|
1603 | 2153 | ts->stat = SAS_DATA_UNDERRUN; |
---|
1604 | | - } else if (complete_hdr->dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) { |
---|
| 2154 | + } else if (dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) { |
---|
1605 | 2155 | ts->stat = SAS_QUEUE_FULL; |
---|
1606 | 2156 | slot->abort = 1; |
---|
1607 | 2157 | } else { |
---|
.. | .. |
---|
1612 | 2162 | case SAS_PROTOCOL_SATA: |
---|
1613 | 2163 | case SAS_PROTOCOL_STP: |
---|
1614 | 2164 | case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: |
---|
1615 | | - if (dma_rx_err_type & RX_DATA_LEN_UNDERFLOW_MSK) { |
---|
| 2165 | + if ((dw0 & CMPLT_HDR_RSPNS_XFRD_MSK) && |
---|
| 2166 | + (sipc_rx_err_type & RX_FIS_STATUS_ERR_MSK)) { |
---|
| 2167 | + ts->stat = SAS_PROTO_RESPONSE; |
---|
| 2168 | + } else if (dma_rx_err_type & RX_DATA_LEN_UNDERFLOW_MSK) { |
---|
1616 | 2169 | ts->residual = trans_tx_fail_type; |
---|
1617 | 2170 | ts->stat = SAS_DATA_UNDERRUN; |
---|
1618 | | - } else if (complete_hdr->dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) { |
---|
| 2171 | + } else if (dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) { |
---|
1619 | 2172 | ts->stat = SAS_PHY_DOWN; |
---|
1620 | 2173 | slot->abort = 1; |
---|
1621 | 2174 | } else { |
---|
1622 | 2175 | ts->stat = SAS_OPEN_REJECT; |
---|
1623 | 2176 | ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; |
---|
1624 | 2177 | } |
---|
1625 | | - hisi_sas_sata_done(task, slot); |
---|
| 2178 | + if (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK) |
---|
| 2179 | + hisi_sas_sata_done(task, slot); |
---|
1626 | 2180 | break; |
---|
1627 | 2181 | case SAS_PROTOCOL_SMP: |
---|
1628 | | - ts->stat = SAM_STAT_CHECK_CONDITION; |
---|
| 2182 | + ts->stat = SAS_SAM_STAT_CHECK_CONDITION; |
---|
1629 | 2183 | break; |
---|
1630 | 2184 | default: |
---|
1631 | 2185 | break; |
---|
1632 | 2186 | } |
---|
| 2187 | + return true; |
---|
1633 | 2188 | } |
---|
1634 | 2189 | |
---|
1635 | | -static int |
---|
1636 | | -slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) |
---|
| 2190 | +static void slot_complete_v3_hw(struct hisi_hba *hisi_hba, |
---|
| 2191 | + struct hisi_sas_slot *slot) |
---|
1637 | 2192 | { |
---|
1638 | 2193 | struct sas_task *task = slot->task; |
---|
1639 | 2194 | struct hisi_sas_device *sas_dev; |
---|
.. | .. |
---|
1641 | 2196 | struct task_status_struct *ts; |
---|
1642 | 2197 | struct domain_device *device; |
---|
1643 | 2198 | struct sas_ha_struct *ha; |
---|
1644 | | - enum exec_status sts; |
---|
1645 | 2199 | struct hisi_sas_complete_v3_hdr *complete_queue = |
---|
1646 | 2200 | hisi_hba->complete_hdr[slot->cmplt_queue]; |
---|
1647 | 2201 | struct hisi_sas_complete_v3_hdr *complete_hdr = |
---|
1648 | 2202 | &complete_queue[slot->cmplt_queue_slot]; |
---|
1649 | 2203 | unsigned long flags; |
---|
1650 | 2204 | bool is_internal = slot->is_internal; |
---|
| 2205 | + u32 dw0, dw1, dw3; |
---|
1651 | 2206 | |
---|
1652 | 2207 | if (unlikely(!task || !task->lldd_task || !task->dev)) |
---|
1653 | | - return -EINVAL; |
---|
| 2208 | + return; |
---|
1654 | 2209 | |
---|
1655 | 2210 | ts = &task->task_status; |
---|
1656 | 2211 | device = task->dev; |
---|
.. | .. |
---|
1671 | 2226 | goto out; |
---|
1672 | 2227 | } |
---|
1673 | 2228 | |
---|
| 2229 | + dw0 = le32_to_cpu(complete_hdr->dw0); |
---|
| 2230 | + dw1 = le32_to_cpu(complete_hdr->dw1); |
---|
| 2231 | + dw3 = le32_to_cpu(complete_hdr->dw3); |
---|
| 2232 | + |
---|
1674 | 2233 | /* |
---|
1675 | 2234 | * Use SAS+TMF status codes |
---|
1676 | 2235 | */ |
---|
1677 | | - switch ((complete_hdr->dw0 & CMPLT_HDR_ABORT_STAT_MSK) |
---|
1678 | | - >> CMPLT_HDR_ABORT_STAT_OFF) { |
---|
| 2236 | + switch ((dw0 & CMPLT_HDR_ABORT_STAT_MSK) >> CMPLT_HDR_ABORT_STAT_OFF) { |
---|
1679 | 2237 | case STAT_IO_ABORTED: |
---|
1680 | 2238 | /* this IO has been aborted by abort command */ |
---|
1681 | 2239 | ts->stat = SAS_ABORTED_TASK; |
---|
.. | .. |
---|
1698 | 2256 | } |
---|
1699 | 2257 | |
---|
1700 | 2258 | /* check for erroneous completion */ |
---|
1701 | | - if ((complete_hdr->dw0 & CMPLT_HDR_CMPLT_MSK) == 0x3) { |
---|
| 2259 | + if ((dw0 & CMPLT_HDR_CMPLT_MSK) == 0x3) { |
---|
1702 | 2260 | u32 *error_info = hisi_sas_status_buf_addr_mem(slot); |
---|
1703 | 2261 | |
---|
1704 | | - slot_err_v3_hw(hisi_hba, task, slot); |
---|
1705 | | - 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; |
---|
1716 | | - goto out; |
---|
| 2262 | + if (slot_err_v3_hw(hisi_hba, task, slot)) { |
---|
| 2263 | + if (ts->stat != SAS_DATA_UNDERRUN) |
---|
| 2264 | + dev_info(dev, "erroneous completion iptt=%d task=%pK dev id=%d addr=%016llx CQ hdr: 0x%x 0x%x 0x%x 0x%x Error info: 0x%x 0x%x 0x%x 0x%x\n", |
---|
| 2265 | + slot->idx, task, sas_dev->device_id, |
---|
| 2266 | + SAS_ADDR(device->sas_addr), |
---|
| 2267 | + dw0, dw1, complete_hdr->act, dw3, |
---|
| 2268 | + error_info[0], error_info[1], |
---|
| 2269 | + error_info[2], error_info[3]); |
---|
| 2270 | + if (unlikely(slot->abort)) { |
---|
| 2271 | + sas_task_abort(task); |
---|
| 2272 | + return; |
---|
| 2273 | + } |
---|
| 2274 | + goto out; |
---|
| 2275 | + } |
---|
1717 | 2276 | } |
---|
1718 | 2277 | |
---|
1719 | 2278 | switch (task->task_proto) { |
---|
.. | .. |
---|
1727 | 2286 | } |
---|
1728 | 2287 | case SAS_PROTOCOL_SMP: { |
---|
1729 | 2288 | struct scatterlist *sg_resp = &task->smp_task.smp_resp; |
---|
1730 | | - void *to; |
---|
| 2289 | + void *to = page_address(sg_page(sg_resp)); |
---|
1731 | 2290 | |
---|
1732 | | - ts->stat = SAM_STAT_GOOD; |
---|
1733 | | - to = kmap_atomic(sg_page(sg_resp)); |
---|
| 2291 | + ts->stat = SAS_SAM_STAT_GOOD; |
---|
1734 | 2292 | |
---|
1735 | | - dma_unmap_sg(dev, &task->smp_task.smp_resp, 1, |
---|
1736 | | - DMA_FROM_DEVICE); |
---|
1737 | 2293 | dma_unmap_sg(dev, &task->smp_task.smp_req, 1, |
---|
1738 | 2294 | DMA_TO_DEVICE); |
---|
1739 | 2295 | memcpy(to + sg_resp->offset, |
---|
1740 | 2296 | hisi_sas_status_buf_addr_mem(slot) + |
---|
1741 | 2297 | sizeof(struct hisi_sas_err_record), |
---|
1742 | | - sg_dma_len(sg_resp)); |
---|
1743 | | - kunmap_atomic(to); |
---|
| 2298 | + sg_resp->length); |
---|
1744 | 2299 | break; |
---|
1745 | 2300 | } |
---|
1746 | 2301 | case SAS_PROTOCOL_SATA: |
---|
1747 | 2302 | case SAS_PROTOCOL_STP: |
---|
1748 | 2303 | case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: |
---|
1749 | | - ts->stat = SAM_STAT_GOOD; |
---|
1750 | | - hisi_sas_sata_done(task, slot); |
---|
| 2304 | + ts->stat = SAS_SAM_STAT_GOOD; |
---|
| 2305 | + if (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK) |
---|
| 2306 | + hisi_sas_sata_done(task, slot); |
---|
1751 | 2307 | break; |
---|
1752 | 2308 | default: |
---|
1753 | | - ts->stat = SAM_STAT_CHECK_CONDITION; |
---|
| 2309 | + ts->stat = SAS_SAM_STAT_CHECK_CONDITION; |
---|
1754 | 2310 | break; |
---|
1755 | 2311 | } |
---|
1756 | 2312 | |
---|
.. | .. |
---|
1761 | 2317 | } |
---|
1762 | 2318 | |
---|
1763 | 2319 | out: |
---|
1764 | | - sts = ts->stat; |
---|
1765 | 2320 | spin_lock_irqsave(&task->task_state_lock, flags); |
---|
1766 | 2321 | if (task->task_state_flags & SAS_TASK_STATE_ABORTED) { |
---|
1767 | 2322 | spin_unlock_irqrestore(&task->task_state_lock, flags); |
---|
1768 | | - dev_info(dev, "slot complete: task(%p) aborted\n", task); |
---|
1769 | | - return SAS_ABORTED_TASK; |
---|
| 2323 | + dev_info(dev, "slot complete: task(%pK) aborted\n", task); |
---|
| 2324 | + return; |
---|
1770 | 2325 | } |
---|
1771 | 2326 | task->task_state_flags |= SAS_TASK_STATE_DONE; |
---|
1772 | 2327 | spin_unlock_irqrestore(&task->task_state_lock, flags); |
---|
.. | .. |
---|
1776 | 2331 | spin_lock_irqsave(&device->done_lock, flags); |
---|
1777 | 2332 | if (test_bit(SAS_HA_FROZEN, &ha->state)) { |
---|
1778 | 2333 | spin_unlock_irqrestore(&device->done_lock, flags); |
---|
1779 | | - dev_info(dev, "slot complete: task(%p) ignored\n ", |
---|
| 2334 | + dev_info(dev, "slot complete: task(%pK) ignored\n ", |
---|
1780 | 2335 | task); |
---|
1781 | | - return sts; |
---|
| 2336 | + return; |
---|
1782 | 2337 | } |
---|
1783 | 2338 | spin_unlock_irqrestore(&device->done_lock, flags); |
---|
1784 | 2339 | } |
---|
1785 | 2340 | |
---|
1786 | 2341 | if (task->task_done) |
---|
1787 | 2342 | task->task_done(task); |
---|
1788 | | - |
---|
1789 | | - return sts; |
---|
1790 | 2343 | } |
---|
1791 | 2344 | |
---|
1792 | | -static void cq_tasklet_v3_hw(unsigned long val) |
---|
| 2345 | +static irqreturn_t cq_thread_v3_hw(int irq_no, void *p) |
---|
1793 | 2346 | { |
---|
1794 | | - struct hisi_sas_cq *cq = (struct hisi_sas_cq *)val; |
---|
| 2347 | + struct hisi_sas_cq *cq = p; |
---|
1795 | 2348 | struct hisi_hba *hisi_hba = cq->hisi_hba; |
---|
1796 | 2349 | struct hisi_sas_slot *slot; |
---|
1797 | 2350 | struct hisi_sas_complete_v3_hdr *complete_queue; |
---|
.. | .. |
---|
1806 | 2359 | while (rd_point != wr_point) { |
---|
1807 | 2360 | struct hisi_sas_complete_v3_hdr *complete_hdr; |
---|
1808 | 2361 | struct device *dev = hisi_hba->dev; |
---|
| 2362 | + u32 dw1; |
---|
1809 | 2363 | int iptt; |
---|
1810 | 2364 | |
---|
1811 | 2365 | complete_hdr = &complete_queue[rd_point]; |
---|
| 2366 | + dw1 = le32_to_cpu(complete_hdr->dw1); |
---|
1812 | 2367 | |
---|
1813 | | - iptt = (complete_hdr->dw1) & CMPLT_HDR_IPTT_MSK; |
---|
| 2368 | + iptt = dw1 & CMPLT_HDR_IPTT_MSK; |
---|
1814 | 2369 | if (likely(iptt < HISI_SAS_COMMAND_ENTRIES_V3_HW)) { |
---|
1815 | 2370 | slot = &hisi_hba->slot_info[iptt]; |
---|
1816 | 2371 | slot->cmplt_queue_slot = rd_point; |
---|
.. | .. |
---|
1826 | 2381 | /* update rd_point */ |
---|
1827 | 2382 | cq->rd_point = rd_point; |
---|
1828 | 2383 | hisi_sas_write32(hisi_hba, COMPL_Q_0_RD_PTR + (0x14 * queue), rd_point); |
---|
| 2384 | + |
---|
| 2385 | + return IRQ_HANDLED; |
---|
1829 | 2386 | } |
---|
1830 | 2387 | |
---|
1831 | 2388 | static irqreturn_t cq_interrupt_v3_hw(int irq_no, void *p) |
---|
.. | .. |
---|
1836 | 2393 | |
---|
1837 | 2394 | hisi_sas_write32(hisi_hba, OQ_INT_SRC, 1 << queue); |
---|
1838 | 2395 | |
---|
1839 | | - tasklet_schedule(&cq->tasklet); |
---|
| 2396 | + return IRQ_WAKE_THREAD; |
---|
| 2397 | +} |
---|
1840 | 2398 | |
---|
1841 | | - return IRQ_HANDLED; |
---|
| 2399 | +static void hisi_sas_v3_free_vectors(void *data) |
---|
| 2400 | +{ |
---|
| 2401 | + struct pci_dev *pdev = data; |
---|
| 2402 | + |
---|
| 2403 | + pci_free_irq_vectors(pdev); |
---|
| 2404 | +} |
---|
| 2405 | + |
---|
| 2406 | +static int interrupt_preinit_v3_hw(struct hisi_hba *hisi_hba) |
---|
| 2407 | +{ |
---|
| 2408 | + int vectors; |
---|
| 2409 | + int max_msi = HISI_SAS_MSI_COUNT_V3_HW, min_msi; |
---|
| 2410 | + struct Scsi_Host *shost = hisi_hba->shost; |
---|
| 2411 | + struct pci_dev *pdev = hisi_hba->pci_dev; |
---|
| 2412 | + struct irq_affinity desc = { |
---|
| 2413 | + .pre_vectors = BASE_VECTORS_V3_HW, |
---|
| 2414 | + }; |
---|
| 2415 | + |
---|
| 2416 | + min_msi = MIN_AFFINE_VECTORS_V3_HW; |
---|
| 2417 | + vectors = pci_alloc_irq_vectors_affinity(pdev, |
---|
| 2418 | + min_msi, max_msi, |
---|
| 2419 | + PCI_IRQ_MSI | |
---|
| 2420 | + PCI_IRQ_AFFINITY, |
---|
| 2421 | + &desc); |
---|
| 2422 | + if (vectors < 0) |
---|
| 2423 | + return -ENOENT; |
---|
| 2424 | + |
---|
| 2425 | + |
---|
| 2426 | + hisi_hba->cq_nvecs = vectors - BASE_VECTORS_V3_HW; |
---|
| 2427 | + shost->nr_hw_queues = hisi_hba->cq_nvecs; |
---|
| 2428 | + |
---|
| 2429 | + return devm_add_action(&pdev->dev, hisi_sas_v3_free_vectors, pdev); |
---|
1842 | 2430 | } |
---|
1843 | 2431 | |
---|
1844 | 2432 | static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) |
---|
1845 | 2433 | { |
---|
1846 | 2434 | struct device *dev = hisi_hba->dev; |
---|
1847 | 2435 | 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 | | - } |
---|
| 2436 | + int rc, i; |
---|
1858 | 2437 | |
---|
1859 | 2438 | rc = devm_request_irq(dev, pci_irq_vector(pdev, 1), |
---|
1860 | 2439 | int_phy_up_down_bcast_v3_hw, 0, |
---|
1861 | 2440 | DRV_NAME " phy", hisi_hba); |
---|
1862 | 2441 | if (rc) { |
---|
1863 | 2442 | dev_err(dev, "could not request phy interrupt, rc=%d\n", rc); |
---|
1864 | | - rc = -ENOENT; |
---|
1865 | | - goto free_irq_vectors; |
---|
| 2443 | + return -ENOENT; |
---|
1866 | 2444 | } |
---|
1867 | 2445 | |
---|
1868 | 2446 | rc = devm_request_irq(dev, pci_irq_vector(pdev, 2), |
---|
.. | .. |
---|
1870 | 2448 | DRV_NAME " channel", hisi_hba); |
---|
1871 | 2449 | if (rc) { |
---|
1872 | 2450 | dev_err(dev, "could not request chnl interrupt, rc=%d\n", rc); |
---|
1873 | | - rc = -ENOENT; |
---|
1874 | | - goto free_phy_irq; |
---|
| 2451 | + return -ENOENT; |
---|
1875 | 2452 | } |
---|
1876 | 2453 | |
---|
1877 | 2454 | rc = devm_request_irq(dev, pci_irq_vector(pdev, 11), |
---|
.. | .. |
---|
1879 | 2456 | DRV_NAME " fatal", hisi_hba); |
---|
1880 | 2457 | if (rc) { |
---|
1881 | 2458 | dev_err(dev, "could not request fatal interrupt, rc=%d\n", rc); |
---|
1882 | | - rc = -ENOENT; |
---|
1883 | | - goto free_chnl_interrupt; |
---|
| 2459 | + return -ENOENT; |
---|
1884 | 2460 | } |
---|
1885 | 2461 | |
---|
1886 | | - /* Init tasklets for cq only */ |
---|
1887 | | - for (i = 0; i < hisi_hba->queue_count; i++) { |
---|
| 2462 | + if (hisi_sas_intr_conv) |
---|
| 2463 | + dev_info(dev, "Enable interrupt converge\n"); |
---|
| 2464 | + |
---|
| 2465 | + for (i = 0; i < hisi_hba->cq_nvecs; i++) { |
---|
1888 | 2466 | struct hisi_sas_cq *cq = &hisi_hba->cq[i]; |
---|
1889 | | - struct tasklet_struct *t = &cq->tasklet; |
---|
| 2467 | + int nr = hisi_sas_intr_conv ? 16 : 16 + i; |
---|
| 2468 | + unsigned long irqflags = hisi_sas_intr_conv ? IRQF_SHARED : |
---|
| 2469 | + IRQF_ONESHOT; |
---|
1890 | 2470 | |
---|
1891 | | - rc = devm_request_irq(dev, pci_irq_vector(pdev, i+16), |
---|
1892 | | - cq_interrupt_v3_hw, 0, |
---|
1893 | | - DRV_NAME " cq", cq); |
---|
| 2471 | + cq->irq_no = pci_irq_vector(pdev, nr); |
---|
| 2472 | + rc = devm_request_threaded_irq(dev, cq->irq_no, |
---|
| 2473 | + cq_interrupt_v3_hw, |
---|
| 2474 | + cq_thread_v3_hw, |
---|
| 2475 | + irqflags, |
---|
| 2476 | + DRV_NAME " cq", cq); |
---|
1894 | 2477 | if (rc) { |
---|
1895 | | - dev_err(dev, |
---|
1896 | | - "could not request cq%d interrupt, rc=%d\n", |
---|
| 2478 | + dev_err(dev, "could not request cq%d interrupt, rc=%d\n", |
---|
1897 | 2479 | i, rc); |
---|
1898 | | - rc = -ENOENT; |
---|
1899 | | - goto free_cq_irqs; |
---|
| 2480 | + return -ENOENT; |
---|
1900 | 2481 | } |
---|
1901 | | - |
---|
1902 | | - tasklet_init(t, cq_tasklet_v3_hw, (unsigned long)cq); |
---|
| 2482 | + cq->irq_mask = pci_irq_get_affinity(pdev, i + BASE_VECTORS_V3_HW); |
---|
| 2483 | + if (!cq->irq_mask) { |
---|
| 2484 | + dev_err(dev, "could not get cq%d irq affinity!\n", i); |
---|
| 2485 | + return -ENOENT; |
---|
| 2486 | + } |
---|
1903 | 2487 | } |
---|
1904 | 2488 | |
---|
1905 | 2489 | 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 | 2490 | } |
---|
1922 | 2491 | |
---|
1923 | 2492 | static int hisi_sas_v3_init(struct hisi_hba *hisi_hba) |
---|
.. | .. |
---|
1939 | 2508 | struct sas_phy_linkrates *r) |
---|
1940 | 2509 | { |
---|
1941 | 2510 | enum sas_linkrate max = r->maximum_linkrate; |
---|
1942 | | - u32 prog_phy_link_rate = 0x800; |
---|
| 2511 | + u32 prog_phy_link_rate = hisi_sas_phy_read32(hisi_hba, phy_no, |
---|
| 2512 | + PROG_PHY_LINK_RATE); |
---|
1943 | 2513 | |
---|
| 2514 | + prog_phy_link_rate &= ~CFG_PROG_PHY_LINK_RATE_MSK; |
---|
1944 | 2515 | prog_phy_link_rate |= hisi_sas_get_prog_phy_linkrate_mask(max); |
---|
1945 | 2516 | hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE, |
---|
1946 | 2517 | prog_phy_link_rate); |
---|
.. | .. |
---|
1954 | 2525 | synchronize_irq(pci_irq_vector(pdev, 1)); |
---|
1955 | 2526 | synchronize_irq(pci_irq_vector(pdev, 2)); |
---|
1956 | 2527 | synchronize_irq(pci_irq_vector(pdev, 11)); |
---|
1957 | | - for (i = 0; i < hisi_hba->queue_count; i++) { |
---|
| 2528 | + for (i = 0; i < hisi_hba->queue_count; i++) |
---|
1958 | 2529 | hisi_sas_write32(hisi_hba, OQ0_INT_SRC_MSK + 0x4 * i, 0x1); |
---|
| 2530 | + |
---|
| 2531 | + for (i = 0; i < hisi_hba->cq_nvecs; i++) |
---|
1959 | 2532 | synchronize_irq(pci_irq_vector(pdev, i + 16)); |
---|
1960 | | - } |
---|
1961 | 2533 | |
---|
1962 | 2534 | hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, 0xffffffff); |
---|
1963 | 2535 | hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK2, 0xffffffff); |
---|
.. | .. |
---|
1978 | 2550 | return hisi_sas_read32(hisi_hba, PHY_STATE); |
---|
1979 | 2551 | } |
---|
1980 | 2552 | |
---|
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 | 2553 | static int disable_host_v3_hw(struct hisi_hba *hisi_hba) |
---|
2007 | 2554 | { |
---|
2008 | 2555 | struct device *dev = hisi_hba->dev; |
---|
.. | .. |
---|
2011 | 2558 | |
---|
2012 | 2559 | interrupt_disable_v3_hw(hisi_hba); |
---|
2013 | 2560 | hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, 0x0); |
---|
2014 | | - hisi_sas_kill_tasklets(hisi_hba); |
---|
2015 | 2561 | |
---|
2016 | 2562 | hisi_sas_stop_phys(hisi_hba); |
---|
2017 | 2563 | |
---|
.. | .. |
---|
2073 | 2619 | break; |
---|
2074 | 2620 | default: |
---|
2075 | 2621 | dev_err(dev, "write gpio: unsupported or bad reg type %d\n", |
---|
2076 | | - reg_type); |
---|
| 2622 | + reg_type); |
---|
2077 | 2623 | return -EINVAL; |
---|
2078 | 2624 | } |
---|
2079 | 2625 | |
---|
.. | .. |
---|
2095 | 2641 | msleep(delay_ms); |
---|
2096 | 2642 | } |
---|
2097 | 2643 | |
---|
| 2644 | + if (time >= timeout_ms) { |
---|
| 2645 | + dev_dbg(dev, "Wait commands complete timeout!\n"); |
---|
| 2646 | + return; |
---|
| 2647 | + } |
---|
| 2648 | + |
---|
2098 | 2649 | dev_dbg(dev, "wait commands complete %dms\n", time); |
---|
| 2650 | +} |
---|
| 2651 | + |
---|
| 2652 | +static ssize_t intr_conv_v3_hw_show(struct device *dev, |
---|
| 2653 | + struct device_attribute *attr, char *buf) |
---|
| 2654 | +{ |
---|
| 2655 | + return scnprintf(buf, PAGE_SIZE, "%u\n", hisi_sas_intr_conv); |
---|
| 2656 | +} |
---|
| 2657 | +static DEVICE_ATTR_RO(intr_conv_v3_hw); |
---|
| 2658 | + |
---|
| 2659 | +static void config_intr_coal_v3_hw(struct hisi_hba *hisi_hba) |
---|
| 2660 | +{ |
---|
| 2661 | + /* config those registers between enable and disable PHYs */ |
---|
| 2662 | + hisi_sas_stop_phys(hisi_hba); |
---|
| 2663 | + |
---|
| 2664 | + if (hisi_hba->intr_coal_ticks == 0 || |
---|
| 2665 | + hisi_hba->intr_coal_count == 0) { |
---|
| 2666 | + hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x1); |
---|
| 2667 | + hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, 0x1); |
---|
| 2668 | + hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, 0x1); |
---|
| 2669 | + } else { |
---|
| 2670 | + hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x3); |
---|
| 2671 | + hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, |
---|
| 2672 | + hisi_hba->intr_coal_ticks); |
---|
| 2673 | + hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, |
---|
| 2674 | + hisi_hba->intr_coal_count); |
---|
| 2675 | + } |
---|
| 2676 | + phys_init_v3_hw(hisi_hba); |
---|
| 2677 | +} |
---|
| 2678 | + |
---|
| 2679 | +static ssize_t intr_coal_ticks_v3_hw_show(struct device *dev, |
---|
| 2680 | + struct device_attribute *attr, |
---|
| 2681 | + char *buf) |
---|
| 2682 | +{ |
---|
| 2683 | + struct Scsi_Host *shost = class_to_shost(dev); |
---|
| 2684 | + struct hisi_hba *hisi_hba = shost_priv(shost); |
---|
| 2685 | + |
---|
| 2686 | + return scnprintf(buf, PAGE_SIZE, "%u\n", |
---|
| 2687 | + hisi_hba->intr_coal_ticks); |
---|
| 2688 | +} |
---|
| 2689 | + |
---|
| 2690 | +static ssize_t intr_coal_ticks_v3_hw_store(struct device *dev, |
---|
| 2691 | + struct device_attribute *attr, |
---|
| 2692 | + const char *buf, size_t count) |
---|
| 2693 | +{ |
---|
| 2694 | + struct Scsi_Host *shost = class_to_shost(dev); |
---|
| 2695 | + struct hisi_hba *hisi_hba = shost_priv(shost); |
---|
| 2696 | + u32 intr_coal_ticks; |
---|
| 2697 | + int ret; |
---|
| 2698 | + |
---|
| 2699 | + ret = kstrtou32(buf, 10, &intr_coal_ticks); |
---|
| 2700 | + if (ret) { |
---|
| 2701 | + dev_err(dev, "Input data of interrupt coalesce unmatch\n"); |
---|
| 2702 | + return -EINVAL; |
---|
| 2703 | + } |
---|
| 2704 | + |
---|
| 2705 | + if (intr_coal_ticks >= BIT(24)) { |
---|
| 2706 | + dev_err(dev, "intr_coal_ticks must be less than 2^24!\n"); |
---|
| 2707 | + return -EINVAL; |
---|
| 2708 | + } |
---|
| 2709 | + |
---|
| 2710 | + hisi_hba->intr_coal_ticks = intr_coal_ticks; |
---|
| 2711 | + |
---|
| 2712 | + config_intr_coal_v3_hw(hisi_hba); |
---|
| 2713 | + |
---|
| 2714 | + return count; |
---|
| 2715 | +} |
---|
| 2716 | +static DEVICE_ATTR_RW(intr_coal_ticks_v3_hw); |
---|
| 2717 | + |
---|
| 2718 | +static ssize_t intr_coal_count_v3_hw_show(struct device *dev, |
---|
| 2719 | + struct device_attribute |
---|
| 2720 | + *attr, char *buf) |
---|
| 2721 | +{ |
---|
| 2722 | + struct Scsi_Host *shost = class_to_shost(dev); |
---|
| 2723 | + struct hisi_hba *hisi_hba = shost_priv(shost); |
---|
| 2724 | + |
---|
| 2725 | + return scnprintf(buf, PAGE_SIZE, "%u\n", |
---|
| 2726 | + hisi_hba->intr_coal_count); |
---|
| 2727 | +} |
---|
| 2728 | + |
---|
| 2729 | +static ssize_t intr_coal_count_v3_hw_store(struct device *dev, |
---|
| 2730 | + struct device_attribute |
---|
| 2731 | + *attr, const char *buf, size_t count) |
---|
| 2732 | +{ |
---|
| 2733 | + struct Scsi_Host *shost = class_to_shost(dev); |
---|
| 2734 | + struct hisi_hba *hisi_hba = shost_priv(shost); |
---|
| 2735 | + u32 intr_coal_count; |
---|
| 2736 | + int ret; |
---|
| 2737 | + |
---|
| 2738 | + ret = kstrtou32(buf, 10, &intr_coal_count); |
---|
| 2739 | + if (ret) { |
---|
| 2740 | + dev_err(dev, "Input data of interrupt coalesce unmatch\n"); |
---|
| 2741 | + return -EINVAL; |
---|
| 2742 | + } |
---|
| 2743 | + |
---|
| 2744 | + if (intr_coal_count >= BIT(8)) { |
---|
| 2745 | + dev_err(dev, "intr_coal_count must be less than 2^8!\n"); |
---|
| 2746 | + return -EINVAL; |
---|
| 2747 | + } |
---|
| 2748 | + |
---|
| 2749 | + hisi_hba->intr_coal_count = intr_coal_count; |
---|
| 2750 | + |
---|
| 2751 | + config_intr_coal_v3_hw(hisi_hba); |
---|
| 2752 | + |
---|
| 2753 | + return count; |
---|
| 2754 | +} |
---|
| 2755 | +static DEVICE_ATTR_RW(intr_coal_count_v3_hw); |
---|
| 2756 | + |
---|
| 2757 | +static int slave_configure_v3_hw(struct scsi_device *sdev) |
---|
| 2758 | +{ |
---|
| 2759 | + struct Scsi_Host *shost = dev_to_shost(&sdev->sdev_gendev); |
---|
| 2760 | + struct domain_device *ddev = sdev_to_domain_dev(sdev); |
---|
| 2761 | + struct hisi_hba *hisi_hba = shost_priv(shost); |
---|
| 2762 | + struct device *dev = hisi_hba->dev; |
---|
| 2763 | + int ret = sas_slave_configure(sdev); |
---|
| 2764 | + |
---|
| 2765 | + if (ret) |
---|
| 2766 | + return ret; |
---|
| 2767 | + if (!dev_is_sata(ddev)) |
---|
| 2768 | + sas_change_queue_depth(sdev, 64); |
---|
| 2769 | + |
---|
| 2770 | + if (sdev->type == TYPE_ENCLOSURE) |
---|
| 2771 | + return 0; |
---|
| 2772 | + |
---|
| 2773 | + if (!device_link_add(&sdev->sdev_gendev, dev, |
---|
| 2774 | + DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE)) { |
---|
| 2775 | + if (pm_runtime_enabled(dev)) { |
---|
| 2776 | + dev_info(dev, "add device link failed, disable runtime PM for the host\n"); |
---|
| 2777 | + pm_runtime_disable(dev); |
---|
| 2778 | + } |
---|
| 2779 | + } |
---|
| 2780 | + |
---|
| 2781 | + return 0; |
---|
| 2782 | +} |
---|
| 2783 | + |
---|
| 2784 | +static struct device_attribute *host_attrs_v3_hw[] = { |
---|
| 2785 | + &dev_attr_phy_event_threshold, |
---|
| 2786 | + &dev_attr_intr_conv_v3_hw, |
---|
| 2787 | + &dev_attr_intr_coal_ticks_v3_hw, |
---|
| 2788 | + &dev_attr_intr_coal_count_v3_hw, |
---|
| 2789 | + NULL |
---|
| 2790 | +}; |
---|
| 2791 | + |
---|
| 2792 | +static const struct hisi_sas_debugfs_reg_lu debugfs_port_reg_lu[] = { |
---|
| 2793 | + HISI_SAS_DEBUGFS_REG(PHY_CFG), |
---|
| 2794 | + HISI_SAS_DEBUGFS_REG(HARD_PHY_LINKRATE), |
---|
| 2795 | + HISI_SAS_DEBUGFS_REG(PROG_PHY_LINK_RATE), |
---|
| 2796 | + HISI_SAS_DEBUGFS_REG(PHY_CTRL), |
---|
| 2797 | + HISI_SAS_DEBUGFS_REG(SL_CFG), |
---|
| 2798 | + HISI_SAS_DEBUGFS_REG(AIP_LIMIT), |
---|
| 2799 | + HISI_SAS_DEBUGFS_REG(SL_CONTROL), |
---|
| 2800 | + HISI_SAS_DEBUGFS_REG(RX_PRIMS_STATUS), |
---|
| 2801 | + HISI_SAS_DEBUGFS_REG(TX_ID_DWORD0), |
---|
| 2802 | + HISI_SAS_DEBUGFS_REG(TX_ID_DWORD1), |
---|
| 2803 | + HISI_SAS_DEBUGFS_REG(TX_ID_DWORD2), |
---|
| 2804 | + HISI_SAS_DEBUGFS_REG(TX_ID_DWORD3), |
---|
| 2805 | + HISI_SAS_DEBUGFS_REG(TX_ID_DWORD4), |
---|
| 2806 | + HISI_SAS_DEBUGFS_REG(TX_ID_DWORD5), |
---|
| 2807 | + HISI_SAS_DEBUGFS_REG(TX_ID_DWORD6), |
---|
| 2808 | + HISI_SAS_DEBUGFS_REG(TXID_AUTO), |
---|
| 2809 | + HISI_SAS_DEBUGFS_REG(RX_IDAF_DWORD0), |
---|
| 2810 | + HISI_SAS_DEBUGFS_REG(RXOP_CHECK_CFG_H), |
---|
| 2811 | + HISI_SAS_DEBUGFS_REG(STP_LINK_TIMER), |
---|
| 2812 | + HISI_SAS_DEBUGFS_REG(STP_LINK_TIMEOUT_STATE), |
---|
| 2813 | + HISI_SAS_DEBUGFS_REG(CON_CFG_DRIVER), |
---|
| 2814 | + HISI_SAS_DEBUGFS_REG(SAS_SSP_CON_TIMER_CFG), |
---|
| 2815 | + HISI_SAS_DEBUGFS_REG(SAS_SMP_CON_TIMER_CFG), |
---|
| 2816 | + HISI_SAS_DEBUGFS_REG(SAS_STP_CON_TIMER_CFG), |
---|
| 2817 | + HISI_SAS_DEBUGFS_REG(CHL_INT0), |
---|
| 2818 | + HISI_SAS_DEBUGFS_REG(CHL_INT1), |
---|
| 2819 | + HISI_SAS_DEBUGFS_REG(CHL_INT2), |
---|
| 2820 | + HISI_SAS_DEBUGFS_REG(CHL_INT0_MSK), |
---|
| 2821 | + HISI_SAS_DEBUGFS_REG(CHL_INT1_MSK), |
---|
| 2822 | + HISI_SAS_DEBUGFS_REG(CHL_INT2_MSK), |
---|
| 2823 | + HISI_SAS_DEBUGFS_REG(SAS_EC_INT_COAL_TIME), |
---|
| 2824 | + HISI_SAS_DEBUGFS_REG(CHL_INT_COAL_EN), |
---|
| 2825 | + HISI_SAS_DEBUGFS_REG(SAS_RX_TRAIN_TIMER), |
---|
| 2826 | + HISI_SAS_DEBUGFS_REG(PHY_CTRL_RDY_MSK), |
---|
| 2827 | + HISI_SAS_DEBUGFS_REG(PHYCTRL_NOT_RDY_MSK), |
---|
| 2828 | + HISI_SAS_DEBUGFS_REG(PHYCTRL_DWS_RESET_MSK), |
---|
| 2829 | + HISI_SAS_DEBUGFS_REG(PHYCTRL_PHY_ENA_MSK), |
---|
| 2830 | + HISI_SAS_DEBUGFS_REG(SL_RX_BCAST_CHK_MSK), |
---|
| 2831 | + HISI_SAS_DEBUGFS_REG(PHYCTRL_OOB_RESTART_MSK), |
---|
| 2832 | + HISI_SAS_DEBUGFS_REG(DMA_TX_STATUS), |
---|
| 2833 | + HISI_SAS_DEBUGFS_REG(DMA_RX_STATUS), |
---|
| 2834 | + HISI_SAS_DEBUGFS_REG(COARSETUNE_TIME), |
---|
| 2835 | + HISI_SAS_DEBUGFS_REG(ERR_CNT_DWS_LOST), |
---|
| 2836 | + HISI_SAS_DEBUGFS_REG(ERR_CNT_RESET_PROB), |
---|
| 2837 | + HISI_SAS_DEBUGFS_REG(ERR_CNT_INVLD_DW), |
---|
| 2838 | + HISI_SAS_DEBUGFS_REG(ERR_CNT_CODE_ERR), |
---|
| 2839 | + HISI_SAS_DEBUGFS_REG(ERR_CNT_DISP_ERR), |
---|
| 2840 | + {} |
---|
| 2841 | +}; |
---|
| 2842 | + |
---|
| 2843 | +static const struct hisi_sas_debugfs_reg debugfs_port_reg = { |
---|
| 2844 | + .lu = debugfs_port_reg_lu, |
---|
| 2845 | + .count = 0x100, |
---|
| 2846 | + .base_off = PORT_BASE, |
---|
| 2847 | + .read_port_reg = hisi_sas_phy_read32, |
---|
| 2848 | +}; |
---|
| 2849 | + |
---|
| 2850 | +static const struct hisi_sas_debugfs_reg_lu debugfs_global_reg_lu[] = { |
---|
| 2851 | + HISI_SAS_DEBUGFS_REG(DLVRY_QUEUE_ENABLE), |
---|
| 2852 | + HISI_SAS_DEBUGFS_REG(PHY_CONTEXT), |
---|
| 2853 | + HISI_SAS_DEBUGFS_REG(PHY_STATE), |
---|
| 2854 | + HISI_SAS_DEBUGFS_REG(PHY_PORT_NUM_MA), |
---|
| 2855 | + HISI_SAS_DEBUGFS_REG(PHY_CONN_RATE), |
---|
| 2856 | + HISI_SAS_DEBUGFS_REG(ITCT_CLR), |
---|
| 2857 | + HISI_SAS_DEBUGFS_REG(IO_SATA_BROKEN_MSG_ADDR_LO), |
---|
| 2858 | + HISI_SAS_DEBUGFS_REG(IO_SATA_BROKEN_MSG_ADDR_HI), |
---|
| 2859 | + HISI_SAS_DEBUGFS_REG(SATA_INITI_D2H_STORE_ADDR_LO), |
---|
| 2860 | + HISI_SAS_DEBUGFS_REG(SATA_INITI_D2H_STORE_ADDR_HI), |
---|
| 2861 | + HISI_SAS_DEBUGFS_REG(CFG_MAX_TAG), |
---|
| 2862 | + HISI_SAS_DEBUGFS_REG(HGC_SAS_TX_OPEN_FAIL_RETRY_CTRL), |
---|
| 2863 | + HISI_SAS_DEBUGFS_REG(HGC_SAS_TXFAIL_RETRY_CTRL), |
---|
| 2864 | + HISI_SAS_DEBUGFS_REG(HGC_GET_ITV_TIME), |
---|
| 2865 | + HISI_SAS_DEBUGFS_REG(DEVICE_MSG_WORK_MODE), |
---|
| 2866 | + HISI_SAS_DEBUGFS_REG(OPENA_WT_CONTI_TIME), |
---|
| 2867 | + HISI_SAS_DEBUGFS_REG(I_T_NEXUS_LOSS_TIME), |
---|
| 2868 | + HISI_SAS_DEBUGFS_REG(MAX_CON_TIME_LIMIT_TIME), |
---|
| 2869 | + HISI_SAS_DEBUGFS_REG(BUS_INACTIVE_LIMIT_TIME), |
---|
| 2870 | + HISI_SAS_DEBUGFS_REG(REJECT_TO_OPEN_LIMIT_TIME), |
---|
| 2871 | + HISI_SAS_DEBUGFS_REG(CQ_INT_CONVERGE_EN), |
---|
| 2872 | + HISI_SAS_DEBUGFS_REG(CFG_AGING_TIME), |
---|
| 2873 | + HISI_SAS_DEBUGFS_REG(HGC_DFX_CFG2), |
---|
| 2874 | + HISI_SAS_DEBUGFS_REG(CFG_ABT_SET_QUERY_IPTT), |
---|
| 2875 | + HISI_SAS_DEBUGFS_REG(CFG_ABT_SET_IPTT_DONE), |
---|
| 2876 | + HISI_SAS_DEBUGFS_REG(HGC_IOMB_PROC1_STATUS), |
---|
| 2877 | + HISI_SAS_DEBUGFS_REG(CHNL_INT_STATUS), |
---|
| 2878 | + HISI_SAS_DEBUGFS_REG(HGC_AXI_FIFO_ERR_INFO), |
---|
| 2879 | + HISI_SAS_DEBUGFS_REG(INT_COAL_EN), |
---|
| 2880 | + HISI_SAS_DEBUGFS_REG(OQ_INT_COAL_TIME), |
---|
| 2881 | + HISI_SAS_DEBUGFS_REG(OQ_INT_COAL_CNT), |
---|
| 2882 | + HISI_SAS_DEBUGFS_REG(ENT_INT_COAL_TIME), |
---|
| 2883 | + HISI_SAS_DEBUGFS_REG(ENT_INT_COAL_CNT), |
---|
| 2884 | + HISI_SAS_DEBUGFS_REG(OQ_INT_SRC), |
---|
| 2885 | + HISI_SAS_DEBUGFS_REG(OQ_INT_SRC_MSK), |
---|
| 2886 | + HISI_SAS_DEBUGFS_REG(ENT_INT_SRC1), |
---|
| 2887 | + HISI_SAS_DEBUGFS_REG(ENT_INT_SRC2), |
---|
| 2888 | + HISI_SAS_DEBUGFS_REG(ENT_INT_SRC3), |
---|
| 2889 | + HISI_SAS_DEBUGFS_REG(ENT_INT_SRC_MSK1), |
---|
| 2890 | + HISI_SAS_DEBUGFS_REG(ENT_INT_SRC_MSK2), |
---|
| 2891 | + HISI_SAS_DEBUGFS_REG(ENT_INT_SRC_MSK3), |
---|
| 2892 | + HISI_SAS_DEBUGFS_REG(CHNL_PHYUPDOWN_INT_MSK), |
---|
| 2893 | + HISI_SAS_DEBUGFS_REG(CHNL_ENT_INT_MSK), |
---|
| 2894 | + HISI_SAS_DEBUGFS_REG(HGC_COM_INT_MSK), |
---|
| 2895 | + HISI_SAS_DEBUGFS_REG(SAS_ECC_INTR), |
---|
| 2896 | + HISI_SAS_DEBUGFS_REG(SAS_ECC_INTR_MSK), |
---|
| 2897 | + HISI_SAS_DEBUGFS_REG(HGC_ERR_STAT_EN), |
---|
| 2898 | + HISI_SAS_DEBUGFS_REG(CQE_SEND_CNT), |
---|
| 2899 | + HISI_SAS_DEBUGFS_REG(DLVRY_Q_0_DEPTH), |
---|
| 2900 | + HISI_SAS_DEBUGFS_REG(DLVRY_Q_0_WR_PTR), |
---|
| 2901 | + HISI_SAS_DEBUGFS_REG(DLVRY_Q_0_RD_PTR), |
---|
| 2902 | + HISI_SAS_DEBUGFS_REG(HYPER_STREAM_ID_EN_CFG), |
---|
| 2903 | + HISI_SAS_DEBUGFS_REG(OQ0_INT_SRC_MSK), |
---|
| 2904 | + HISI_SAS_DEBUGFS_REG(COMPL_Q_0_DEPTH), |
---|
| 2905 | + HISI_SAS_DEBUGFS_REG(COMPL_Q_0_WR_PTR), |
---|
| 2906 | + HISI_SAS_DEBUGFS_REG(COMPL_Q_0_RD_PTR), |
---|
| 2907 | + HISI_SAS_DEBUGFS_REG(AWQOS_AWCACHE_CFG), |
---|
| 2908 | + HISI_SAS_DEBUGFS_REG(ARQOS_ARCACHE_CFG), |
---|
| 2909 | + HISI_SAS_DEBUGFS_REG(HILINK_ERR_DFX), |
---|
| 2910 | + HISI_SAS_DEBUGFS_REG(SAS_GPIO_CFG_0), |
---|
| 2911 | + HISI_SAS_DEBUGFS_REG(SAS_GPIO_CFG_1), |
---|
| 2912 | + HISI_SAS_DEBUGFS_REG(SAS_GPIO_TX_0_1), |
---|
| 2913 | + HISI_SAS_DEBUGFS_REG(SAS_CFG_DRIVE_VLD), |
---|
| 2914 | + {} |
---|
| 2915 | +}; |
---|
| 2916 | + |
---|
| 2917 | +static const struct hisi_sas_debugfs_reg debugfs_global_reg = { |
---|
| 2918 | + .lu = debugfs_global_reg_lu, |
---|
| 2919 | + .count = 0x800, |
---|
| 2920 | + .read_global_reg = hisi_sas_read32, |
---|
| 2921 | +}; |
---|
| 2922 | + |
---|
| 2923 | +static const struct hisi_sas_debugfs_reg_lu debugfs_axi_reg_lu[] = { |
---|
| 2924 | + HISI_SAS_DEBUGFS_REG(AM_CFG_MAX_TRANS), |
---|
| 2925 | + HISI_SAS_DEBUGFS_REG(AM_CFG_SINGLE_PORT_MAX_TRANS), |
---|
| 2926 | + HISI_SAS_DEBUGFS_REG(AXI_CFG), |
---|
| 2927 | + HISI_SAS_DEBUGFS_REG(AM_ROB_ECC_ERR_ADDR), |
---|
| 2928 | + {} |
---|
| 2929 | +}; |
---|
| 2930 | + |
---|
| 2931 | +static const struct hisi_sas_debugfs_reg debugfs_axi_reg = { |
---|
| 2932 | + .lu = debugfs_axi_reg_lu, |
---|
| 2933 | + .count = 0x61, |
---|
| 2934 | + .base_off = AXI_MASTER_CFG_BASE, |
---|
| 2935 | + .read_global_reg = hisi_sas_read32, |
---|
| 2936 | +}; |
---|
| 2937 | + |
---|
| 2938 | +static const struct hisi_sas_debugfs_reg_lu debugfs_ras_reg_lu[] = { |
---|
| 2939 | + HISI_SAS_DEBUGFS_REG(SAS_RAS_INTR0), |
---|
| 2940 | + HISI_SAS_DEBUGFS_REG(SAS_RAS_INTR1), |
---|
| 2941 | + HISI_SAS_DEBUGFS_REG(SAS_RAS_INTR0_MASK), |
---|
| 2942 | + HISI_SAS_DEBUGFS_REG(SAS_RAS_INTR1_MASK), |
---|
| 2943 | + HISI_SAS_DEBUGFS_REG(CFG_SAS_RAS_INTR_MASK), |
---|
| 2944 | + HISI_SAS_DEBUGFS_REG(SAS_RAS_INTR2), |
---|
| 2945 | + HISI_SAS_DEBUGFS_REG(SAS_RAS_INTR2_MASK), |
---|
| 2946 | + {} |
---|
| 2947 | +}; |
---|
| 2948 | + |
---|
| 2949 | +static const struct hisi_sas_debugfs_reg debugfs_ras_reg = { |
---|
| 2950 | + .lu = debugfs_ras_reg_lu, |
---|
| 2951 | + .count = 0x10, |
---|
| 2952 | + .base_off = RAS_BASE, |
---|
| 2953 | + .read_global_reg = hisi_sas_read32, |
---|
| 2954 | +}; |
---|
| 2955 | + |
---|
| 2956 | +static void debugfs_snapshot_prepare_v3_hw(struct hisi_hba *hisi_hba) |
---|
| 2957 | +{ |
---|
| 2958 | + set_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); |
---|
| 2959 | + |
---|
| 2960 | + hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, 0); |
---|
| 2961 | + |
---|
| 2962 | + wait_cmds_complete_timeout_v3_hw(hisi_hba, 100, 5000); |
---|
| 2963 | + |
---|
| 2964 | + hisi_sas_sync_irqs(hisi_hba); |
---|
| 2965 | +} |
---|
| 2966 | + |
---|
| 2967 | +static void debugfs_snapshot_restore_v3_hw(struct hisi_hba *hisi_hba) |
---|
| 2968 | +{ |
---|
| 2969 | + hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, |
---|
| 2970 | + (u32)((1ULL << hisi_hba->queue_count) - 1)); |
---|
| 2971 | + |
---|
| 2972 | + clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); |
---|
| 2973 | +} |
---|
| 2974 | + |
---|
| 2975 | +static void read_iost_itct_cache_v3_hw(struct hisi_hba *hisi_hba, |
---|
| 2976 | + enum hisi_sas_debugfs_cache_type type, |
---|
| 2977 | + u32 *cache) |
---|
| 2978 | +{ |
---|
| 2979 | + u32 cache_dw_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * |
---|
| 2980 | + HISI_SAS_IOST_ITCT_CACHE_NUM; |
---|
| 2981 | + struct device *dev = hisi_hba->dev; |
---|
| 2982 | + u32 *buf = cache; |
---|
| 2983 | + u32 i, val; |
---|
| 2984 | + |
---|
| 2985 | + hisi_sas_write32(hisi_hba, TAB_RD_TYPE, type); |
---|
| 2986 | + |
---|
| 2987 | + for (i = 0; i < HISI_SAS_IOST_ITCT_CACHE_DW_SZ; i++) { |
---|
| 2988 | + val = hisi_sas_read32(hisi_hba, TAB_DFX); |
---|
| 2989 | + if (val == 0xffffffff) |
---|
| 2990 | + break; |
---|
| 2991 | + } |
---|
| 2992 | + |
---|
| 2993 | + if (val != 0xffffffff) { |
---|
| 2994 | + dev_err(dev, "Issue occurred in reading IOST/ITCT cache!\n"); |
---|
| 2995 | + return; |
---|
| 2996 | + } |
---|
| 2997 | + |
---|
| 2998 | + memset(buf, 0, cache_dw_size * 4); |
---|
| 2999 | + buf[0] = val; |
---|
| 3000 | + |
---|
| 3001 | + for (i = 1; i < cache_dw_size; i++) |
---|
| 3002 | + buf[i] = hisi_sas_read32(hisi_hba, TAB_DFX); |
---|
| 3003 | +} |
---|
| 3004 | + |
---|
| 3005 | +static void hisi_sas_bist_test_prep_v3_hw(struct hisi_hba *hisi_hba) |
---|
| 3006 | +{ |
---|
| 3007 | + u32 reg_val; |
---|
| 3008 | + int phy_no = hisi_hba->debugfs_bist_phy_no; |
---|
| 3009 | + int i; |
---|
| 3010 | + |
---|
| 3011 | + /* disable PHY */ |
---|
| 3012 | + hisi_sas_phy_enable(hisi_hba, phy_no, 0); |
---|
| 3013 | + |
---|
| 3014 | + /* update FFE */ |
---|
| 3015 | + for (i = 0; i < FFE_CFG_MAX; i++) |
---|
| 3016 | + hisi_sas_phy_write32(hisi_hba, phy_no, TXDEEMPH_G1 + (i * 0x4), |
---|
| 3017 | + hisi_hba->debugfs_bist_ffe[phy_no][i]); |
---|
| 3018 | + |
---|
| 3019 | + /* disable ALOS */ |
---|
| 3020 | + reg_val = hisi_sas_phy_read32(hisi_hba, phy_no, SERDES_CFG); |
---|
| 3021 | + reg_val |= CFG_ALOS_CHK_DISABLE_MSK; |
---|
| 3022 | + hisi_sas_phy_write32(hisi_hba, phy_no, SERDES_CFG, reg_val); |
---|
| 3023 | +} |
---|
| 3024 | + |
---|
| 3025 | +static void hisi_sas_bist_test_restore_v3_hw(struct hisi_hba *hisi_hba) |
---|
| 3026 | +{ |
---|
| 3027 | + u32 reg_val; |
---|
| 3028 | + int phy_no = hisi_hba->debugfs_bist_phy_no; |
---|
| 3029 | + |
---|
| 3030 | + /* disable loopback */ |
---|
| 3031 | + reg_val = hisi_sas_phy_read32(hisi_hba, phy_no, SAS_PHY_BIST_CTRL); |
---|
| 3032 | + reg_val &= ~(CFG_RX_BIST_EN_MSK | CFG_TX_BIST_EN_MSK | |
---|
| 3033 | + CFG_BIST_TEST_MSK); |
---|
| 3034 | + hisi_sas_phy_write32(hisi_hba, phy_no, SAS_PHY_BIST_CTRL, reg_val); |
---|
| 3035 | + |
---|
| 3036 | + /* enable ALOS */ |
---|
| 3037 | + reg_val = hisi_sas_phy_read32(hisi_hba, phy_no, SERDES_CFG); |
---|
| 3038 | + reg_val &= ~CFG_ALOS_CHK_DISABLE_MSK; |
---|
| 3039 | + hisi_sas_phy_write32(hisi_hba, phy_no, SERDES_CFG, reg_val); |
---|
| 3040 | + |
---|
| 3041 | + /* restore the linkrate */ |
---|
| 3042 | + reg_val = hisi_sas_phy_read32(hisi_hba, phy_no, PROG_PHY_LINK_RATE); |
---|
| 3043 | + /* init OOB link rate as 1.5 Gbits */ |
---|
| 3044 | + reg_val &= ~CFG_PROG_OOB_PHY_LINK_RATE_MSK; |
---|
| 3045 | + reg_val |= (0x8 << CFG_PROG_OOB_PHY_LINK_RATE_OFF); |
---|
| 3046 | + hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE, reg_val); |
---|
| 3047 | + |
---|
| 3048 | + /* enable PHY */ |
---|
| 3049 | + hisi_sas_phy_enable(hisi_hba, phy_no, 1); |
---|
| 3050 | +} |
---|
| 3051 | + |
---|
| 3052 | +#define SAS_PHY_BIST_CODE_INIT 0x1 |
---|
| 3053 | +#define SAS_PHY_BIST_CODE1_INIT 0X80 |
---|
| 3054 | +static int debugfs_set_bist_v3_hw(struct hisi_hba *hisi_hba, bool enable) |
---|
| 3055 | +{ |
---|
| 3056 | + u32 reg_val, mode_tmp; |
---|
| 3057 | + u32 linkrate = hisi_hba->debugfs_bist_linkrate; |
---|
| 3058 | + u32 phy_no = hisi_hba->debugfs_bist_phy_no; |
---|
| 3059 | + u32 *ffe = hisi_hba->debugfs_bist_ffe[phy_no]; |
---|
| 3060 | + u32 code_mode = hisi_hba->debugfs_bist_code_mode; |
---|
| 3061 | + u32 path_mode = hisi_hba->debugfs_bist_mode; |
---|
| 3062 | + u32 *fix_code = &hisi_hba->debugfs_bist_fixed_code[0]; |
---|
| 3063 | + struct device *dev = hisi_hba->dev; |
---|
| 3064 | + |
---|
| 3065 | + 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", |
---|
| 3066 | + phy_no, linkrate, code_mode, path_mode, |
---|
| 3067 | + ffe[FFE_SAS_1_5_GBPS], ffe[FFE_SAS_3_0_GBPS], |
---|
| 3068 | + ffe[FFE_SAS_6_0_GBPS], ffe[FFE_SAS_12_0_GBPS], |
---|
| 3069 | + ffe[FFE_SATA_1_5_GBPS], ffe[FFE_SATA_3_0_GBPS], |
---|
| 3070 | + ffe[FFE_SATA_6_0_GBPS], fix_code[FIXED_CODE], |
---|
| 3071 | + fix_code[FIXED_CODE_1]); |
---|
| 3072 | + mode_tmp = path_mode ? 2 : 1; |
---|
| 3073 | + if (enable) { |
---|
| 3074 | + /* some preparations before bist test */ |
---|
| 3075 | + hisi_sas_bist_test_prep_v3_hw(hisi_hba); |
---|
| 3076 | + |
---|
| 3077 | + /* set linkrate of bit test*/ |
---|
| 3078 | + reg_val = hisi_sas_phy_read32(hisi_hba, phy_no, |
---|
| 3079 | + PROG_PHY_LINK_RATE); |
---|
| 3080 | + reg_val &= ~CFG_PROG_OOB_PHY_LINK_RATE_MSK; |
---|
| 3081 | + reg_val |= (linkrate << CFG_PROG_OOB_PHY_LINK_RATE_OFF); |
---|
| 3082 | + hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE, |
---|
| 3083 | + reg_val); |
---|
| 3084 | + |
---|
| 3085 | + /* set code mode of bit test */ |
---|
| 3086 | + reg_val = hisi_sas_phy_read32(hisi_hba, phy_no, |
---|
| 3087 | + SAS_PHY_BIST_CTRL); |
---|
| 3088 | + reg_val &= ~(CFG_BIST_MODE_SEL_MSK | CFG_LOOP_TEST_MODE_MSK | |
---|
| 3089 | + CFG_RX_BIST_EN_MSK | CFG_TX_BIST_EN_MSK | |
---|
| 3090 | + CFG_BIST_TEST_MSK); |
---|
| 3091 | + reg_val |= ((code_mode << CFG_BIST_MODE_SEL_OFF) | |
---|
| 3092 | + (mode_tmp << CFG_LOOP_TEST_MODE_OFF) | |
---|
| 3093 | + CFG_BIST_TEST_MSK); |
---|
| 3094 | + hisi_sas_phy_write32(hisi_hba, phy_no, SAS_PHY_BIST_CTRL, |
---|
| 3095 | + reg_val); |
---|
| 3096 | + |
---|
| 3097 | + /* set the bist init value */ |
---|
| 3098 | + if (code_mode == HISI_SAS_BIST_CODE_MODE_FIXED_DATA) { |
---|
| 3099 | + reg_val = hisi_hba->debugfs_bist_fixed_code[0]; |
---|
| 3100 | + hisi_sas_phy_write32(hisi_hba, phy_no, |
---|
| 3101 | + SAS_PHY_BIST_CODE, reg_val); |
---|
| 3102 | + |
---|
| 3103 | + reg_val = hisi_hba->debugfs_bist_fixed_code[1]; |
---|
| 3104 | + hisi_sas_phy_write32(hisi_hba, phy_no, |
---|
| 3105 | + SAS_PHY_BIST_CODE1, reg_val); |
---|
| 3106 | + } else { |
---|
| 3107 | + hisi_sas_phy_write32(hisi_hba, phy_no, |
---|
| 3108 | + SAS_PHY_BIST_CODE, |
---|
| 3109 | + SAS_PHY_BIST_CODE_INIT); |
---|
| 3110 | + hisi_sas_phy_write32(hisi_hba, phy_no, |
---|
| 3111 | + SAS_PHY_BIST_CODE1, |
---|
| 3112 | + SAS_PHY_BIST_CODE1_INIT); |
---|
| 3113 | + } |
---|
| 3114 | + |
---|
| 3115 | + mdelay(100); |
---|
| 3116 | + reg_val |= (CFG_RX_BIST_EN_MSK | CFG_TX_BIST_EN_MSK); |
---|
| 3117 | + hisi_sas_phy_write32(hisi_hba, phy_no, SAS_PHY_BIST_CTRL, |
---|
| 3118 | + reg_val); |
---|
| 3119 | + |
---|
| 3120 | + /* clear error bit */ |
---|
| 3121 | + mdelay(100); |
---|
| 3122 | + hisi_sas_phy_read32(hisi_hba, phy_no, SAS_BIST_ERR_CNT); |
---|
| 3123 | + } else { |
---|
| 3124 | + /* disable bist test and recover it */ |
---|
| 3125 | + hisi_hba->debugfs_bist_cnt += hisi_sas_phy_read32(hisi_hba, |
---|
| 3126 | + phy_no, SAS_BIST_ERR_CNT); |
---|
| 3127 | + hisi_sas_bist_test_restore_v3_hw(hisi_hba); |
---|
| 3128 | + } |
---|
| 3129 | + |
---|
| 3130 | + return 0; |
---|
| 3131 | +} |
---|
| 3132 | + |
---|
| 3133 | +static int hisi_sas_map_queues(struct Scsi_Host *shost) |
---|
| 3134 | +{ |
---|
| 3135 | + struct hisi_hba *hisi_hba = shost_priv(shost); |
---|
| 3136 | + struct blk_mq_queue_map *qmap = &shost->tag_set.map[HCTX_TYPE_DEFAULT]; |
---|
| 3137 | + |
---|
| 3138 | + return blk_mq_pci_map_queues(qmap, hisi_hba->pci_dev, |
---|
| 3139 | + BASE_VECTORS_V3_HW); |
---|
2099 | 3140 | } |
---|
2100 | 3141 | |
---|
2101 | 3142 | static struct scsi_host_template sht_v3_hw = { |
---|
2102 | 3143 | .name = DRV_NAME, |
---|
| 3144 | + .proc_name = DRV_NAME, |
---|
2103 | 3145 | .module = THIS_MODULE, |
---|
2104 | 3146 | .queuecommand = sas_queuecommand, |
---|
| 3147 | + .dma_need_drain = ata_scsi_dma_need_drain, |
---|
2105 | 3148 | .target_alloc = sas_target_alloc, |
---|
2106 | | - .slave_configure = hisi_sas_slave_configure, |
---|
| 3149 | + .slave_configure = slave_configure_v3_hw, |
---|
2107 | 3150 | .scan_finished = hisi_sas_scan_finished, |
---|
2108 | 3151 | .scan_start = hisi_sas_scan_start, |
---|
| 3152 | + .map_queues = hisi_sas_map_queues, |
---|
2109 | 3153 | .change_queue_depth = sas_change_queue_depth, |
---|
2110 | 3154 | .bios_param = sas_bios_param, |
---|
2111 | | - .can_queue = 1, |
---|
2112 | 3155 | .this_id = -1, |
---|
2113 | | - .sg_tablesize = SG_ALL, |
---|
| 3156 | + .sg_tablesize = HISI_SAS_SGE_PAGE_CNT, |
---|
| 3157 | + .sg_prot_tablesize = HISI_SAS_SGE_PAGE_CNT, |
---|
2114 | 3158 | .max_sectors = SCSI_DEFAULT_MAX_SECTORS, |
---|
2115 | | - .use_clustering = ENABLE_CLUSTERING, |
---|
2116 | 3159 | .eh_device_reset_handler = sas_eh_device_reset_handler, |
---|
2117 | 3160 | .eh_target_reset_handler = sas_eh_target_reset_handler, |
---|
2118 | 3161 | .slave_alloc = sas_slave_alloc, |
---|
2119 | 3162 | .target_destroy = sas_target_destroy, |
---|
2120 | 3163 | .ioctl = sas_ioctl, |
---|
2121 | | - .shost_attrs = host_attrs, |
---|
| 3164 | +#ifdef CONFIG_COMPAT |
---|
| 3165 | + .compat_ioctl = sas_ioctl, |
---|
| 3166 | +#endif |
---|
| 3167 | + .shost_attrs = host_attrs_v3_hw, |
---|
| 3168 | + .tag_alloc_policy = BLK_TAG_ALLOC_RR, |
---|
| 3169 | + .host_reset = hisi_sas_host_reset, |
---|
| 3170 | + .host_tagset = 1, |
---|
2122 | 3171 | }; |
---|
2123 | 3172 | |
---|
2124 | 3173 | static const struct hisi_sas_hw hisi_sas_v3_hw = { |
---|
2125 | 3174 | .hw_init = hisi_sas_v3_init, |
---|
2126 | 3175 | .setup_itct = setup_itct_v3_hw, |
---|
2127 | | - .max_command_entries = HISI_SAS_COMMAND_ENTRIES_V3_HW, |
---|
2128 | 3176 | .get_wideport_bitmap = get_wideport_bitmap_v3_hw, |
---|
2129 | 3177 | .complete_hdr_size = sizeof(struct hisi_sas_complete_v3_hdr), |
---|
2130 | 3178 | .clear_itct = clear_itct_v3_hw, |
---|
.. | .. |
---|
2133 | 3181 | .prep_smp = prep_smp_v3_hw, |
---|
2134 | 3182 | .prep_stp = prep_ata_v3_hw, |
---|
2135 | 3183 | .prep_abort = prep_abort_v3_hw, |
---|
2136 | | - .get_free_slot = get_free_slot_v3_hw, |
---|
2137 | 3184 | .start_delivery = start_delivery_v3_hw, |
---|
2138 | | - .slot_complete = slot_complete_v3_hw, |
---|
2139 | 3185 | .phys_init = phys_init_v3_hw, |
---|
2140 | 3186 | .phy_start = start_phy_v3_hw, |
---|
2141 | 3187 | .phy_disable = disable_phy_v3_hw, |
---|
.. | .. |
---|
2148 | 3194 | .get_events = phy_get_events_v3_hw, |
---|
2149 | 3195 | .write_gpio = write_gpio_v3_hw, |
---|
2150 | 3196 | .wait_cmds_complete_timeout = wait_cmds_complete_timeout_v3_hw, |
---|
| 3197 | + .debugfs_reg_array[DEBUGFS_GLOBAL] = &debugfs_global_reg, |
---|
| 3198 | + .debugfs_reg_array[DEBUGFS_AXI] = &debugfs_axi_reg, |
---|
| 3199 | + .debugfs_reg_array[DEBUGFS_RAS] = &debugfs_ras_reg, |
---|
| 3200 | + .debugfs_reg_port = &debugfs_port_reg, |
---|
| 3201 | + .snapshot_prepare = debugfs_snapshot_prepare_v3_hw, |
---|
| 3202 | + .snapshot_restore = debugfs_snapshot_restore_v3_hw, |
---|
| 3203 | + .read_iost_itct_cache = read_iost_itct_cache_v3_hw, |
---|
| 3204 | + .set_bist = debugfs_set_bist_v3_hw, |
---|
2151 | 3205 | }; |
---|
2152 | 3206 | |
---|
2153 | 3207 | static struct Scsi_Host * |
---|
.. | .. |
---|
2165 | 3219 | hisi_hba = shost_priv(shost); |
---|
2166 | 3220 | |
---|
2167 | 3221 | INIT_WORK(&hisi_hba->rst_work, hisi_sas_rst_work_handler); |
---|
| 3222 | + INIT_WORK(&hisi_hba->debugfs_work, hisi_sas_debugfs_work_handler); |
---|
2168 | 3223 | hisi_hba->hw = &hisi_sas_v3_hw; |
---|
2169 | 3224 | hisi_hba->pci_dev = pdev; |
---|
2170 | 3225 | hisi_hba->dev = dev; |
---|
2171 | 3226 | hisi_hba->shost = shost; |
---|
2172 | 3227 | SHOST_TO_SAS_HA(shost) = &hisi_hba->sha; |
---|
2173 | 3228 | |
---|
2174 | | - timer_setup(&hisi_hba->timer, NULL, 0); |
---|
| 3229 | + if (prot_mask & ~HISI_SAS_PROT_MASK) |
---|
| 3230 | + dev_err(dev, "unsupported protection mask 0x%x, using default (0x0)\n", |
---|
| 3231 | + prot_mask); |
---|
| 3232 | + else |
---|
| 3233 | + hisi_hba->prot_mask = prot_mask; |
---|
2175 | 3234 | |
---|
2176 | 3235 | if (hisi_sas_get_fw_info(hisi_hba) < 0) |
---|
2177 | 3236 | goto err_out; |
---|
2178 | 3237 | |
---|
2179 | | - if (hisi_sas_alloc(hisi_hba, shost)) { |
---|
| 3238 | + if (hisi_sas_alloc(hisi_hba)) { |
---|
2180 | 3239 | hisi_sas_free(hisi_hba); |
---|
2181 | 3240 | goto err_out; |
---|
2182 | 3241 | } |
---|
.. | .. |
---|
2209 | 3268 | if (rc) |
---|
2210 | 3269 | goto err_out_disable_device; |
---|
2211 | 3270 | |
---|
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 | | - } |
---|
| 3271 | + rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); |
---|
| 3272 | + if (rc) |
---|
| 3273 | + rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); |
---|
| 3274 | + if (rc) { |
---|
| 3275 | + dev_err(dev, "No usable DMA addressing method\n"); |
---|
| 3276 | + rc = -ENODEV; |
---|
| 3277 | + goto err_out_regions; |
---|
2220 | 3278 | } |
---|
2221 | 3279 | |
---|
2222 | 3280 | shost = hisi_sas_shost_alloc_pci(pdev); |
---|
.. | .. |
---|
2231 | 3289 | |
---|
2232 | 3290 | hisi_hba->regs = pcim_iomap(pdev, 5, 0); |
---|
2233 | 3291 | if (!hisi_hba->regs) { |
---|
2234 | | - dev_err(dev, "cannot map register.\n"); |
---|
| 3292 | + dev_err(dev, "cannot map register\n"); |
---|
2235 | 3293 | rc = -ENOMEM; |
---|
2236 | 3294 | goto err_out_ha; |
---|
2237 | 3295 | } |
---|
.. | .. |
---|
2255 | 3313 | shost->max_lun = ~0; |
---|
2256 | 3314 | shost->max_channel = 1; |
---|
2257 | 3315 | 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; |
---|
| 3316 | + shost->can_queue = HISI_SAS_UNRESERVED_IPTT; |
---|
| 3317 | + shost->cmd_per_lun = HISI_SAS_UNRESERVED_IPTT; |
---|
2261 | 3318 | |
---|
2262 | 3319 | sha->sas_ha_name = DRV_NAME; |
---|
2263 | 3320 | sha->dev = dev; |
---|
2264 | 3321 | sha->lldd_module = THIS_MODULE; |
---|
2265 | 3322 | sha->sas_addr = &hisi_hba->sas_addr[0]; |
---|
2266 | 3323 | sha->num_phys = hisi_hba->n_phy; |
---|
2267 | | - sha->core.shost = hisi_hba->shost; |
---|
2268 | 3324 | |
---|
2269 | 3325 | for (i = 0; i < hisi_hba->n_phy; i++) { |
---|
2270 | 3326 | sha->sas_phy[i] = &hisi_hba->phy[i].sas_phy; |
---|
2271 | 3327 | sha->sas_port[i] = &hisi_hba->port[i].sas_port; |
---|
2272 | 3328 | } |
---|
2273 | 3329 | |
---|
| 3330 | + if (hisi_hba->prot_mask) { |
---|
| 3331 | + dev_info(dev, "Registering for DIF/DIX prot_mask=0x%x\n", |
---|
| 3332 | + prot_mask); |
---|
| 3333 | + scsi_host_set_prot(hisi_hba->shost, prot_mask); |
---|
| 3334 | + if (hisi_hba->prot_mask & HISI_SAS_DIX_PROT_MASK) |
---|
| 3335 | + scsi_host_set_guard(hisi_hba->shost, |
---|
| 3336 | + SHOST_DIX_GUARD_CRC); |
---|
| 3337 | + } |
---|
| 3338 | + |
---|
| 3339 | + if (hisi_sas_debugfs_enable) |
---|
| 3340 | + hisi_sas_debugfs_init(hisi_hba); |
---|
| 3341 | + |
---|
| 3342 | + rc = interrupt_preinit_v3_hw(hisi_hba); |
---|
| 3343 | + if (rc) |
---|
| 3344 | + goto err_out_debugfs; |
---|
| 3345 | + dev_err(dev, "%d hw queues\n", shost->nr_hw_queues); |
---|
2274 | 3346 | rc = scsi_add_host(shost, dev); |
---|
2275 | 3347 | if (rc) |
---|
2276 | | - goto err_out_ha; |
---|
| 3348 | + goto err_out_debugfs; |
---|
2277 | 3349 | |
---|
2278 | 3350 | rc = sas_register_ha(sha); |
---|
2279 | 3351 | if (rc) |
---|
.. | .. |
---|
2285 | 3357 | |
---|
2286 | 3358 | scsi_scan_host(shost); |
---|
2287 | 3359 | |
---|
| 3360 | + /* |
---|
| 3361 | + * For the situation that there are ATA disks connected with SAS |
---|
| 3362 | + * controller, it additionally creates ata_port which will affect the |
---|
| 3363 | + * child_count of hisi_hba->dev. Even if suspended all the disks, |
---|
| 3364 | + * ata_port is still and the child_count of hisi_hba->dev is not 0. |
---|
| 3365 | + * So use pm_suspend_ignore_children() to ignore the effect to |
---|
| 3366 | + * hisi_hba->dev. |
---|
| 3367 | + */ |
---|
| 3368 | + pm_suspend_ignore_children(dev, true); |
---|
| 3369 | + pm_runtime_put_noidle(&pdev->dev); |
---|
| 3370 | + |
---|
2288 | 3371 | return 0; |
---|
2289 | 3372 | |
---|
2290 | 3373 | err_out_register_ha: |
---|
2291 | 3374 | scsi_remove_host(shost); |
---|
| 3375 | +err_out_debugfs: |
---|
| 3376 | + hisi_sas_debugfs_exit(hisi_hba); |
---|
2292 | 3377 | err_out_ha: |
---|
| 3378 | + hisi_sas_free(hisi_hba); |
---|
2293 | 3379 | scsi_host_put(shost); |
---|
2294 | 3380 | err_out_regions: |
---|
2295 | 3381 | pci_release_regions(pdev); |
---|
.. | .. |
---|
2304 | 3390 | { |
---|
2305 | 3391 | int i; |
---|
2306 | 3392 | |
---|
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++) { |
---|
| 3393 | + devm_free_irq(&pdev->dev, pci_irq_vector(pdev, 1), hisi_hba); |
---|
| 3394 | + devm_free_irq(&pdev->dev, pci_irq_vector(pdev, 2), hisi_hba); |
---|
| 3395 | + devm_free_irq(&pdev->dev, pci_irq_vector(pdev, 11), hisi_hba); |
---|
| 3396 | + for (i = 0; i < hisi_hba->cq_nvecs; i++) { |
---|
2311 | 3397 | struct hisi_sas_cq *cq = &hisi_hba->cq[i]; |
---|
| 3398 | + int nr = hisi_sas_intr_conv ? 16 : 16 + i; |
---|
2312 | 3399 | |
---|
2313 | | - free_irq(pci_irq_vector(pdev, i+16), cq); |
---|
| 3400 | + devm_free_irq(&pdev->dev, pci_irq_vector(pdev, nr), cq); |
---|
2314 | 3401 | } |
---|
2315 | | - pci_free_irq_vectors(pdev); |
---|
2316 | 3402 | } |
---|
2317 | 3403 | |
---|
2318 | 3404 | static void hisi_sas_v3_remove(struct pci_dev *pdev) |
---|
.. | .. |
---|
2322 | 3408 | struct hisi_hba *hisi_hba = sha->lldd_ha; |
---|
2323 | 3409 | struct Scsi_Host *shost = sha->core.shost; |
---|
2324 | 3410 | |
---|
| 3411 | + pm_runtime_get_noresume(dev); |
---|
2325 | 3412 | if (timer_pending(&hisi_hba->timer)) |
---|
2326 | 3413 | del_timer(&hisi_hba->timer); |
---|
2327 | 3414 | |
---|
.. | .. |
---|
2329 | 3416 | sas_remove_host(sha->core.shost); |
---|
2330 | 3417 | |
---|
2331 | 3418 | hisi_sas_v3_destroy_irqs(pdev, hisi_hba); |
---|
2332 | | - hisi_sas_kill_tasklets(hisi_hba); |
---|
2333 | 3419 | pci_release_regions(pdev); |
---|
2334 | 3420 | pci_disable_device(pdev); |
---|
2335 | 3421 | hisi_sas_free(hisi_hba); |
---|
| 3422 | + hisi_sas_debugfs_exit(hisi_hba); |
---|
2336 | 3423 | 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 | 3424 | } |
---|
2493 | 3425 | |
---|
2494 | 3426 | static void hisi_sas_reset_prepare_v3_hw(struct pci_dev *pdev) |
---|
.. | .. |
---|
2531 | 3463 | hip08, |
---|
2532 | 3464 | }; |
---|
2533 | 3465 | |
---|
2534 | | -static int hisi_sas_v3_suspend(struct pci_dev *pdev, pm_message_t state) |
---|
| 3466 | +static int _suspend_v3_hw(struct device *device) |
---|
2535 | 3467 | { |
---|
| 3468 | + struct pci_dev *pdev = to_pci_dev(device); |
---|
2536 | 3469 | struct sas_ha_struct *sha = pci_get_drvdata(pdev); |
---|
2537 | 3470 | struct hisi_hba *hisi_hba = sha->lldd_ha; |
---|
2538 | 3471 | struct device *dev = hisi_hba->dev; |
---|
2539 | 3472 | struct Scsi_Host *shost = hisi_hba->shost; |
---|
2540 | | - u32 device_state; |
---|
| 3473 | + pci_power_t device_state; |
---|
2541 | 3474 | int rc; |
---|
2542 | 3475 | |
---|
2543 | 3476 | if (!pdev->pm_cap) { |
---|
.. | .. |
---|
2563 | 3496 | |
---|
2564 | 3497 | hisi_sas_init_mem(hisi_hba); |
---|
2565 | 3498 | |
---|
2566 | | - device_state = pci_choose_state(pdev, state); |
---|
| 3499 | + device_state = pci_choose_state(pdev, PMSG_SUSPEND); |
---|
2567 | 3500 | dev_warn(dev, "entering operating state [D%d]\n", |
---|
2568 | 3501 | device_state); |
---|
2569 | 3502 | pci_save_state(pdev); |
---|
.. | .. |
---|
2576 | 3509 | return 0; |
---|
2577 | 3510 | } |
---|
2578 | 3511 | |
---|
2579 | | -static int hisi_sas_v3_resume(struct pci_dev *pdev) |
---|
| 3512 | +static int _resume_v3_hw(struct device *device) |
---|
2580 | 3513 | { |
---|
| 3514 | + struct pci_dev *pdev = to_pci_dev(device); |
---|
2581 | 3515 | struct sas_ha_struct *sha = pci_get_drvdata(pdev); |
---|
2582 | 3516 | struct hisi_hba *hisi_hba = sha->lldd_ha; |
---|
2583 | 3517 | struct Scsi_Host *shost = hisi_hba->shost; |
---|
2584 | 3518 | struct device *dev = hisi_hba->dev; |
---|
2585 | 3519 | unsigned int rc; |
---|
2586 | | - u32 device_state = pdev->current_state; |
---|
| 3520 | + pci_power_t device_state = pdev->current_state; |
---|
2587 | 3521 | |
---|
2588 | 3522 | dev_warn(dev, "resuming from operating state [D%d]\n", |
---|
2589 | | - device_state); |
---|
| 3523 | + device_state); |
---|
2590 | 3524 | pci_set_power_state(pdev, PCI_D0); |
---|
2591 | 3525 | pci_enable_wake(pdev, PCI_D0, 0); |
---|
2592 | 3526 | pci_restore_state(pdev); |
---|
2593 | 3527 | rc = pci_enable_device(pdev); |
---|
2594 | | - if (rc) |
---|
| 3528 | + if (rc) { |
---|
2595 | 3529 | dev_err(dev, "enable device failed during resume (%d)\n", rc); |
---|
| 3530 | + return rc; |
---|
| 3531 | + } |
---|
2596 | 3532 | |
---|
2597 | 3533 | pci_set_master(pdev); |
---|
2598 | 3534 | scsi_unblock_requests(shost); |
---|
2599 | 3535 | clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); |
---|
2600 | 3536 | |
---|
2601 | 3537 | sas_prep_resume_ha(sha); |
---|
2602 | | - init_reg_v3_hw(hisi_hba); |
---|
| 3538 | + rc = hw_init_v3_hw(hisi_hba); |
---|
| 3539 | + if (rc) { |
---|
| 3540 | + scsi_remove_host(shost); |
---|
| 3541 | + pci_disable_device(pdev); |
---|
| 3542 | + return rc; |
---|
| 3543 | + } |
---|
2603 | 3544 | hisi_hba->hw->phys_init(hisi_hba); |
---|
2604 | 3545 | sas_resume_ha(sha); |
---|
2605 | 3546 | clear_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags); |
---|
2606 | 3547 | |
---|
2607 | 3548 | return 0; |
---|
| 3549 | +} |
---|
| 3550 | + |
---|
| 3551 | +static int suspend_v3_hw(struct device *device) |
---|
| 3552 | +{ |
---|
| 3553 | + struct pci_dev *pdev = to_pci_dev(device); |
---|
| 3554 | + struct sas_ha_struct *sha = pci_get_drvdata(pdev); |
---|
| 3555 | + struct hisi_hba *hisi_hba = sha->lldd_ha; |
---|
| 3556 | + int rc; |
---|
| 3557 | + |
---|
| 3558 | + set_bit(HISI_SAS_PM_BIT, &hisi_hba->flags); |
---|
| 3559 | + |
---|
| 3560 | + rc = _suspend_v3_hw(device); |
---|
| 3561 | + if (rc) |
---|
| 3562 | + clear_bit(HISI_SAS_PM_BIT, &hisi_hba->flags); |
---|
| 3563 | + |
---|
| 3564 | + return rc; |
---|
| 3565 | +} |
---|
| 3566 | + |
---|
| 3567 | +static int resume_v3_hw(struct device *device) |
---|
| 3568 | +{ |
---|
| 3569 | + struct pci_dev *pdev = to_pci_dev(device); |
---|
| 3570 | + struct sas_ha_struct *sha = pci_get_drvdata(pdev); |
---|
| 3571 | + struct hisi_hba *hisi_hba = sha->lldd_ha; |
---|
| 3572 | + int rc = _resume_v3_hw(device); |
---|
| 3573 | + |
---|
| 3574 | + clear_bit(HISI_SAS_PM_BIT, &hisi_hba->flags); |
---|
| 3575 | + |
---|
| 3576 | + return rc; |
---|
2608 | 3577 | } |
---|
2609 | 3578 | |
---|
2610 | 3579 | static const struct pci_device_id sas_v3_pci_table[] = { |
---|
.. | .. |
---|
2614 | 3583 | MODULE_DEVICE_TABLE(pci, sas_v3_pci_table); |
---|
2615 | 3584 | |
---|
2616 | 3585 | 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 | 3586 | .reset_prepare = hisi_sas_reset_prepare_v3_hw, |
---|
2621 | 3587 | .reset_done = hisi_sas_reset_done_v3_hw, |
---|
| 3588 | +}; |
---|
| 3589 | + |
---|
| 3590 | +static int runtime_suspend_v3_hw(struct device *dev) |
---|
| 3591 | +{ |
---|
| 3592 | + return suspend_v3_hw(dev); |
---|
| 3593 | +} |
---|
| 3594 | + |
---|
| 3595 | +static int runtime_resume_v3_hw(struct device *dev) |
---|
| 3596 | +{ |
---|
| 3597 | + return resume_v3_hw(dev); |
---|
| 3598 | +} |
---|
| 3599 | + |
---|
| 3600 | +static const struct dev_pm_ops hisi_sas_v3_pm_ops = { |
---|
| 3601 | + SET_SYSTEM_SLEEP_PM_OPS(suspend_v3_hw, resume_v3_hw) |
---|
| 3602 | + SET_RUNTIME_PM_OPS(runtime_suspend_v3_hw, |
---|
| 3603 | + runtime_resume_v3_hw, NULL) |
---|
2622 | 3604 | }; |
---|
2623 | 3605 | |
---|
2624 | 3606 | static struct pci_driver sas_v3_pci_driver = { |
---|
.. | .. |
---|
2626 | 3608 | .id_table = sas_v3_pci_table, |
---|
2627 | 3609 | .probe = hisi_sas_v3_probe, |
---|
2628 | 3610 | .remove = hisi_sas_v3_remove, |
---|
2629 | | - .suspend = hisi_sas_v3_suspend, |
---|
2630 | | - .resume = hisi_sas_v3_resume, |
---|
2631 | 3611 | .err_handler = &hisi_sas_err_handler, |
---|
| 3612 | + .driver.pm = &hisi_sas_v3_pm_ops, |
---|
2632 | 3613 | }; |
---|
2633 | 3614 | |
---|
2634 | 3615 | module_pci_driver(sas_v3_pci_driver); |
---|
| 3616 | +module_param_named(intr_conv, hisi_sas_intr_conv, bool, 0444); |
---|
2635 | 3617 | |
---|
2636 | 3618 | MODULE_LICENSE("GPL"); |
---|
2637 | 3619 | MODULE_AUTHOR("John Garry <john.garry@huawei.com>"); |
---|