brintos

brintos / linux-shallow public Read only

0
0
Text · 106.0 KiB · 342d75f Raw
3648 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Copyright (c) 2016 Linaro Ltd.4 * Copyright (c) 2016 Hisilicon Limited.5 */6 7#include "hisi_sas.h"8#define DRV_NAME "hisi_sas_v2_hw"9 10/* global registers need init*/11#define DLVRY_QUEUE_ENABLE		0x012#define IOST_BASE_ADDR_LO		0x813#define IOST_BASE_ADDR_HI		0xc14#define ITCT_BASE_ADDR_LO		0x1015#define ITCT_BASE_ADDR_HI		0x1416#define IO_BROKEN_MSG_ADDR_LO		0x1817#define IO_BROKEN_MSG_ADDR_HI		0x1c18#define PHY_CONTEXT			0x2019#define PHY_STATE			0x2420#define PHY_PORT_NUM_MA			0x2821#define PORT_STATE			0x2c22#define PORT_STATE_PHY8_PORT_NUM_OFF	1623#define PORT_STATE_PHY8_PORT_NUM_MSK	(0xf << PORT_STATE_PHY8_PORT_NUM_OFF)24#define PORT_STATE_PHY8_CONN_RATE_OFF	2025#define PORT_STATE_PHY8_CONN_RATE_MSK	(0xf << PORT_STATE_PHY8_CONN_RATE_OFF)26#define PHY_CONN_RATE			0x3027#define HGC_TRANS_TASK_CNT_LIMIT	0x3828#define AXI_AHB_CLK_CFG			0x3c29#define ITCT_CLR			0x4430#define ITCT_CLR_EN_OFF			1631#define ITCT_CLR_EN_MSK			(0x1 << ITCT_CLR_EN_OFF)32#define ITCT_DEV_OFF			033#define ITCT_DEV_MSK			(0x7ff << ITCT_DEV_OFF)34#define AXI_USER1			0x4835#define AXI_USER2			0x4c36#define IO_SATA_BROKEN_MSG_ADDR_LO	0x5837#define IO_SATA_BROKEN_MSG_ADDR_HI	0x5c38#define SATA_INITI_D2H_STORE_ADDR_LO	0x6039#define SATA_INITI_D2H_STORE_ADDR_HI	0x6440#define HGC_SAS_TX_OPEN_FAIL_RETRY_CTRL	0x8441#define HGC_SAS_TXFAIL_RETRY_CTRL	0x8842#define HGC_GET_ITV_TIME		0x9043#define DEVICE_MSG_WORK_MODE		0x9444#define OPENA_WT_CONTI_TIME		0x9c45#define I_T_NEXUS_LOSS_TIME		0xa046#define MAX_CON_TIME_LIMIT_TIME		0xa447#define BUS_INACTIVE_LIMIT_TIME		0xa848#define REJECT_TO_OPEN_LIMIT_TIME	0xac49#define CFG_AGING_TIME			0xbc50#define HGC_DFX_CFG2			0xc051#define HGC_IOMB_PROC1_STATUS	0x10452#define CFG_1US_TIMER_TRSH		0xcc53#define HGC_LM_DFX_STATUS2		0x12854#define HGC_LM_DFX_STATUS2_IOSTLIST_OFF		055#define HGC_LM_DFX_STATUS2_IOSTLIST_MSK	(0xfff << \56					 HGC_LM_DFX_STATUS2_IOSTLIST_OFF)57#define HGC_LM_DFX_STATUS2_ITCTLIST_OFF		1258#define HGC_LM_DFX_STATUS2_ITCTLIST_MSK	(0x7ff << \59					 HGC_LM_DFX_STATUS2_ITCTLIST_OFF)60#define HGC_CQE_ECC_ADDR		0x13c61#define HGC_CQE_ECC_1B_ADDR_OFF	062#define HGC_CQE_ECC_1B_ADDR_MSK	(0x3f << HGC_CQE_ECC_1B_ADDR_OFF)63#define HGC_CQE_ECC_MB_ADDR_OFF	864#define HGC_CQE_ECC_MB_ADDR_MSK (0x3f << HGC_CQE_ECC_MB_ADDR_OFF)65#define HGC_IOST_ECC_ADDR		0x14066#define HGC_IOST_ECC_1B_ADDR_OFF	067#define HGC_IOST_ECC_1B_ADDR_MSK	(0x3ff << HGC_IOST_ECC_1B_ADDR_OFF)68#define HGC_IOST_ECC_MB_ADDR_OFF	1669#define HGC_IOST_ECC_MB_ADDR_MSK	(0x3ff << HGC_IOST_ECC_MB_ADDR_OFF)70#define HGC_DQE_ECC_ADDR		0x14471#define HGC_DQE_ECC_1B_ADDR_OFF	072#define HGC_DQE_ECC_1B_ADDR_MSK	(0xfff << HGC_DQE_ECC_1B_ADDR_OFF)73#define HGC_DQE_ECC_MB_ADDR_OFF	1674#define HGC_DQE_ECC_MB_ADDR_MSK (0xfff << HGC_DQE_ECC_MB_ADDR_OFF)75#define HGC_INVLD_DQE_INFO		0x14876#define HGC_INVLD_DQE_INFO_FB_CH0_OFF	977#define HGC_INVLD_DQE_INFO_FB_CH0_MSK	(0x1 << HGC_INVLD_DQE_INFO_FB_CH0_OFF)78#define HGC_INVLD_DQE_INFO_FB_CH3_OFF	1879#define HGC_ITCT_ECC_ADDR		0x15080#define HGC_ITCT_ECC_1B_ADDR_OFF		081#define HGC_ITCT_ECC_1B_ADDR_MSK		(0x3ff << \82						 HGC_ITCT_ECC_1B_ADDR_OFF)83#define HGC_ITCT_ECC_MB_ADDR_OFF		1684#define HGC_ITCT_ECC_MB_ADDR_MSK		(0x3ff << \85						 HGC_ITCT_ECC_MB_ADDR_OFF)86#define HGC_AXI_FIFO_ERR_INFO	0x15487#define AXI_ERR_INFO_OFF		088#define AXI_ERR_INFO_MSK		(0xff << AXI_ERR_INFO_OFF)89#define FIFO_ERR_INFO_OFF		890#define FIFO_ERR_INFO_MSK		(0xff << FIFO_ERR_INFO_OFF)91#define INT_COAL_EN			0x19c92#define OQ_INT_COAL_TIME		0x1a093#define OQ_INT_COAL_CNT			0x1a494#define ENT_INT_COAL_TIME		0x1a895#define ENT_INT_COAL_CNT		0x1ac96#define OQ_INT_SRC			0x1b097#define OQ_INT_SRC_MSK			0x1b498#define ENT_INT_SRC1			0x1b899#define ENT_INT_SRC1_D2H_FIS_CH0_OFF	0100#define ENT_INT_SRC1_D2H_FIS_CH0_MSK	(0x1 << ENT_INT_SRC1_D2H_FIS_CH0_OFF)101#define ENT_INT_SRC1_D2H_FIS_CH1_OFF	8102#define ENT_INT_SRC1_D2H_FIS_CH1_MSK	(0x1 << ENT_INT_SRC1_D2H_FIS_CH1_OFF)103#define ENT_INT_SRC2			0x1bc104#define ENT_INT_SRC3			0x1c0105#define ENT_INT_SRC3_WP_DEPTH_OFF		8106#define ENT_INT_SRC3_IPTT_SLOT_NOMATCH_OFF	9107#define ENT_INT_SRC3_RP_DEPTH_OFF		10108#define ENT_INT_SRC3_AXI_OFF			11109#define ENT_INT_SRC3_FIFO_OFF			12110#define ENT_INT_SRC3_LM_OFF				14111#define ENT_INT_SRC3_ITC_INT_OFF	15112#define ENT_INT_SRC3_ITC_INT_MSK	(0x1 << ENT_INT_SRC3_ITC_INT_OFF)113#define ENT_INT_SRC3_ABT_OFF		16114#define ENT_INT_SRC_MSK1		0x1c4115#define ENT_INT_SRC_MSK2		0x1c8116#define ENT_INT_SRC_MSK3		0x1cc117#define ENT_INT_SRC_MSK3_ENT95_MSK_OFF	31118#define ENT_INT_SRC_MSK3_ENT95_MSK_MSK	(0x1 << ENT_INT_SRC_MSK3_ENT95_MSK_OFF)119#define SAS_ECC_INTR			0x1e8120#define SAS_ECC_INTR_DQE_ECC_1B_OFF		0121#define SAS_ECC_INTR_DQE_ECC_MB_OFF		1122#define SAS_ECC_INTR_IOST_ECC_1B_OFF	2123#define SAS_ECC_INTR_IOST_ECC_MB_OFF	3124#define SAS_ECC_INTR_ITCT_ECC_MB_OFF	4125#define SAS_ECC_INTR_ITCT_ECC_1B_OFF	5126#define SAS_ECC_INTR_IOSTLIST_ECC_MB_OFF	6127#define SAS_ECC_INTR_IOSTLIST_ECC_1B_OFF	7128#define SAS_ECC_INTR_ITCTLIST_ECC_1B_OFF	8129#define SAS_ECC_INTR_ITCTLIST_ECC_MB_OFF	9130#define SAS_ECC_INTR_CQE_ECC_1B_OFF		10131#define SAS_ECC_INTR_CQE_ECC_MB_OFF		11132#define SAS_ECC_INTR_NCQ_MEM0_ECC_MB_OFF	12133#define SAS_ECC_INTR_NCQ_MEM0_ECC_1B_OFF	13134#define SAS_ECC_INTR_NCQ_MEM1_ECC_MB_OFF	14135#define SAS_ECC_INTR_NCQ_MEM1_ECC_1B_OFF	15136#define SAS_ECC_INTR_NCQ_MEM2_ECC_MB_OFF	16137#define SAS_ECC_INTR_NCQ_MEM2_ECC_1B_OFF	17138#define SAS_ECC_INTR_NCQ_MEM3_ECC_MB_OFF	18139#define SAS_ECC_INTR_NCQ_MEM3_ECC_1B_OFF	19140#define SAS_ECC_INTR_MSK		0x1ec141#define HGC_ERR_STAT_EN			0x238142#define CQE_SEND_CNT			0x248143#define DLVRY_Q_0_BASE_ADDR_LO		0x260144#define DLVRY_Q_0_BASE_ADDR_HI		0x264145#define DLVRY_Q_0_DEPTH			0x268146#define DLVRY_Q_0_WR_PTR		0x26c147#define DLVRY_Q_0_RD_PTR		0x270148#define HYPER_STREAM_ID_EN_CFG		0xc80149#define OQ0_INT_SRC_MSK			0xc90150#define COMPL_Q_0_BASE_ADDR_LO		0x4e0151#define COMPL_Q_0_BASE_ADDR_HI		0x4e4152#define COMPL_Q_0_DEPTH			0x4e8153#define COMPL_Q_0_WR_PTR		0x4ec154#define COMPL_Q_0_RD_PTR		0x4f0155#define HGC_RXM_DFX_STATUS14	0xae8156#define HGC_RXM_DFX_STATUS14_MEM0_OFF		0157#define HGC_RXM_DFX_STATUS14_MEM0_MSK		(0x1ff << \158						 HGC_RXM_DFX_STATUS14_MEM0_OFF)159#define HGC_RXM_DFX_STATUS14_MEM1_OFF		9160#define HGC_RXM_DFX_STATUS14_MEM1_MSK		(0x1ff << \161						 HGC_RXM_DFX_STATUS14_MEM1_OFF)162#define HGC_RXM_DFX_STATUS14_MEM2_OFF		18163#define HGC_RXM_DFX_STATUS14_MEM2_MSK		(0x1ff << \164						 HGC_RXM_DFX_STATUS14_MEM2_OFF)165#define HGC_RXM_DFX_STATUS15	0xaec166#define HGC_RXM_DFX_STATUS15_MEM3_OFF		0167#define HGC_RXM_DFX_STATUS15_MEM3_MSK		(0x1ff << \168						 HGC_RXM_DFX_STATUS15_MEM3_OFF)169/* phy registers need init */170#define PORT_BASE			(0x2000)171 172#define PHY_CFG				(PORT_BASE + 0x0)173#define HARD_PHY_LINKRATE		(PORT_BASE + 0x4)174#define PHY_CFG_ENA_OFF			0175#define PHY_CFG_ENA_MSK			(0x1 << PHY_CFG_ENA_OFF)176#define PHY_CFG_DC_OPT_OFF		2177#define PHY_CFG_DC_OPT_MSK		(0x1 << PHY_CFG_DC_OPT_OFF)178#define PROG_PHY_LINK_RATE		(PORT_BASE + 0x8)179#define PROG_PHY_LINK_RATE_MAX_OFF	0180#define PROG_PHY_LINK_RATE_MAX_MSK	(0xff << PROG_PHY_LINK_RATE_MAX_OFF)181#define PHY_CTRL			(PORT_BASE + 0x14)182#define PHY_CTRL_RESET_OFF		0183#define PHY_CTRL_RESET_MSK		(0x1 << PHY_CTRL_RESET_OFF)184#define SAS_PHY_CTRL			(PORT_BASE + 0x20)185#define SL_CFG				(PORT_BASE + 0x84)186#define PHY_PCN				(PORT_BASE + 0x44)187#define SL_TOUT_CFG			(PORT_BASE + 0x8c)188#define SL_CONTROL			(PORT_BASE + 0x94)189#define SL_CONTROL_NOTIFY_EN_OFF	0190#define SL_CONTROL_NOTIFY_EN_MSK	(0x1 << SL_CONTROL_NOTIFY_EN_OFF)191#define SL_CONTROL_CTA_OFF		17192#define SL_CONTROL_CTA_MSK		(0x1 << SL_CONTROL_CTA_OFF)193#define RX_PRIMS_STATUS			(PORT_BASE + 0x98)194#define RX_BCAST_CHG_OFF		1195#define RX_BCAST_CHG_MSK		(0x1 << RX_BCAST_CHG_OFF)196#define TX_ID_DWORD0			(PORT_BASE + 0x9c)197#define TX_ID_DWORD1			(PORT_BASE + 0xa0)198#define TX_ID_DWORD2			(PORT_BASE + 0xa4)199#define TX_ID_DWORD3			(PORT_BASE + 0xa8)200#define TX_ID_DWORD4			(PORT_BASE + 0xaC)201#define TX_ID_DWORD5			(PORT_BASE + 0xb0)202#define TX_ID_DWORD6			(PORT_BASE + 0xb4)203#define TXID_AUTO			(PORT_BASE + 0xb8)204#define TXID_AUTO_CT3_OFF		1205#define TXID_AUTO_CT3_MSK		(0x1 << TXID_AUTO_CT3_OFF)206#define TXID_AUTO_CTB_OFF		11207#define TXID_AUTO_CTB_MSK		(0x1 << TXID_AUTO_CTB_OFF)208#define TX_HARDRST_OFF			2209#define TX_HARDRST_MSK			(0x1 << TX_HARDRST_OFF)210#define RX_IDAF_DWORD0			(PORT_BASE + 0xc4)211#define RX_IDAF_DWORD1			(PORT_BASE + 0xc8)212#define RX_IDAF_DWORD2			(PORT_BASE + 0xcc)213#define RX_IDAF_DWORD3			(PORT_BASE + 0xd0)214#define RX_IDAF_DWORD4			(PORT_BASE + 0xd4)215#define RX_IDAF_DWORD5			(PORT_BASE + 0xd8)216#define RX_IDAF_DWORD6			(PORT_BASE + 0xdc)217#define RXOP_CHECK_CFG_H		(PORT_BASE + 0xfc)218#define CON_CONTROL			(PORT_BASE + 0x118)219#define CON_CONTROL_CFG_OPEN_ACC_STP_OFF	0220#define CON_CONTROL_CFG_OPEN_ACC_STP_MSK	\221		(0x01 << CON_CONTROL_CFG_OPEN_ACC_STP_OFF)222#define DONE_RECEIVED_TIME		(PORT_BASE + 0x11c)223#define CHL_INT0			(PORT_BASE + 0x1b4)224#define CHL_INT0_HOTPLUG_TOUT_OFF	0225#define CHL_INT0_HOTPLUG_TOUT_MSK	(0x1 << CHL_INT0_HOTPLUG_TOUT_OFF)226#define CHL_INT0_SL_RX_BCST_ACK_OFF	1227#define CHL_INT0_SL_RX_BCST_ACK_MSK	(0x1 << CHL_INT0_SL_RX_BCST_ACK_OFF)228#define CHL_INT0_SL_PHY_ENABLE_OFF	2229#define CHL_INT0_SL_PHY_ENABLE_MSK	(0x1 << CHL_INT0_SL_PHY_ENABLE_OFF)230#define CHL_INT0_NOT_RDY_OFF		4231#define CHL_INT0_NOT_RDY_MSK		(0x1 << CHL_INT0_NOT_RDY_OFF)232#define CHL_INT0_PHY_RDY_OFF		5233#define CHL_INT0_PHY_RDY_MSK		(0x1 << CHL_INT0_PHY_RDY_OFF)234#define CHL_INT1			(PORT_BASE + 0x1b8)235#define CHL_INT1_DMAC_TX_ECC_ERR_OFF	15236#define CHL_INT1_DMAC_TX_ECC_ERR_MSK	(0x1 << CHL_INT1_DMAC_TX_ECC_ERR_OFF)237#define CHL_INT1_DMAC_RX_ECC_ERR_OFF	17238#define CHL_INT1_DMAC_RX_ECC_ERR_MSK	(0x1 << CHL_INT1_DMAC_RX_ECC_ERR_OFF)239#define CHL_INT1_DMAC_TX_AXI_WR_ERR_OFF	19240#define CHL_INT1_DMAC_TX_AXI_RD_ERR_OFF	20241#define CHL_INT1_DMAC_RX_AXI_WR_ERR_OFF	21242#define CHL_INT1_DMAC_RX_AXI_RD_ERR_OFF	22243#define CHL_INT2			(PORT_BASE + 0x1bc)244#define CHL_INT2_SL_IDAF_TOUT_CONF_OFF	0245#define CHL_INT0_MSK			(PORT_BASE + 0x1c0)246#define CHL_INT1_MSK			(PORT_BASE + 0x1c4)247#define CHL_INT2_MSK			(PORT_BASE + 0x1c8)248#define CHL_INT_COAL_EN			(PORT_BASE + 0x1d0)249#define DMA_TX_DFX0				(PORT_BASE + 0x200)250#define DMA_TX_DFX1				(PORT_BASE + 0x204)251#define DMA_TX_DFX1_IPTT_OFF		0252#define DMA_TX_DFX1_IPTT_MSK		(0xffff << DMA_TX_DFX1_IPTT_OFF)253#define DMA_TX_FIFO_DFX0		(PORT_BASE + 0x240)254#define PORT_DFX0				(PORT_BASE + 0x258)255#define LINK_DFX2					(PORT_BASE + 0X264)256#define LINK_DFX2_RCVR_HOLD_STS_OFF	9257#define LINK_DFX2_RCVR_HOLD_STS_MSK	(0x1 << LINK_DFX2_RCVR_HOLD_STS_OFF)258#define LINK_DFX2_SEND_HOLD_STS_OFF	10259#define LINK_DFX2_SEND_HOLD_STS_MSK	(0x1 << LINK_DFX2_SEND_HOLD_STS_OFF)260#define SAS_ERR_CNT4_REG		(PORT_BASE + 0x290)261#define SAS_ERR_CNT6_REG		(PORT_BASE + 0x298)262#define PHY_CTRL_RDY_MSK		(PORT_BASE + 0x2b0)263#define PHYCTRL_NOT_RDY_MSK		(PORT_BASE + 0x2b4)264#define PHYCTRL_DWS_RESET_MSK		(PORT_BASE + 0x2b8)265#define PHYCTRL_PHY_ENA_MSK		(PORT_BASE + 0x2bc)266#define SL_RX_BCAST_CHK_MSK		(PORT_BASE + 0x2c0)267#define PHYCTRL_OOB_RESTART_MSK		(PORT_BASE + 0x2c4)268#define DMA_TX_STATUS			(PORT_BASE + 0x2d0)269#define DMA_TX_STATUS_BUSY_OFF		0270#define DMA_TX_STATUS_BUSY_MSK		(0x1 << DMA_TX_STATUS_BUSY_OFF)271#define DMA_RX_STATUS			(PORT_BASE + 0x2e8)272#define DMA_RX_STATUS_BUSY_OFF		0273#define DMA_RX_STATUS_BUSY_MSK		(0x1 << DMA_RX_STATUS_BUSY_OFF)274 275#define AXI_CFG				(0x5100)276#define AM_CFG_MAX_TRANS		(0x5010)277#define AM_CFG_SINGLE_PORT_MAX_TRANS	(0x5014)278 279#define AXI_MASTER_CFG_BASE		(0x5000)280#define AM_CTRL_GLOBAL			(0x0)281#define AM_CURR_TRANS_RETURN	(0x150)282 283/* HW dma structures */284/* Delivery queue header */285/* dw0 */286#define CMD_HDR_ABORT_FLAG_OFF		0287#define CMD_HDR_ABORT_FLAG_MSK		(0x3 << CMD_HDR_ABORT_FLAG_OFF)288#define CMD_HDR_ABORT_DEVICE_TYPE_OFF	2289#define CMD_HDR_ABORT_DEVICE_TYPE_MSK	(0x1 << CMD_HDR_ABORT_DEVICE_TYPE_OFF)290#define CMD_HDR_RESP_REPORT_OFF		5291#define CMD_HDR_RESP_REPORT_MSK		(0x1 << CMD_HDR_RESP_REPORT_OFF)292#define CMD_HDR_TLR_CTRL_OFF		6293#define CMD_HDR_TLR_CTRL_MSK		(0x3 << CMD_HDR_TLR_CTRL_OFF)294#define CMD_HDR_PHY_ID_OFF		8295#define CMD_HDR_PHY_ID_MSK		(0x1ff << CMD_HDR_PHY_ID_OFF)296#define CMD_HDR_FORCE_PHY_OFF		17297#define CMD_HDR_FORCE_PHY_MSK		(0x1 << CMD_HDR_FORCE_PHY_OFF)298#define CMD_HDR_PORT_OFF		18299#define CMD_HDR_PORT_MSK		(0xf << CMD_HDR_PORT_OFF)300#define CMD_HDR_PRIORITY_OFF		27301#define CMD_HDR_PRIORITY_MSK		(0x1 << CMD_HDR_PRIORITY_OFF)302#define CMD_HDR_CMD_OFF			29303#define CMD_HDR_CMD_MSK			(0x7 << CMD_HDR_CMD_OFF)304/* dw1 */305#define CMD_HDR_DIR_OFF			5306#define CMD_HDR_DIR_MSK			(0x3 << CMD_HDR_DIR_OFF)307#define CMD_HDR_RESET_OFF		7308#define CMD_HDR_RESET_MSK		(0x1 << CMD_HDR_RESET_OFF)309#define CMD_HDR_VDTL_OFF		10310#define CMD_HDR_VDTL_MSK		(0x1 << CMD_HDR_VDTL_OFF)311#define CMD_HDR_FRAME_TYPE_OFF		11312#define CMD_HDR_FRAME_TYPE_MSK		(0x1f << CMD_HDR_FRAME_TYPE_OFF)313#define CMD_HDR_DEV_ID_OFF		16314#define CMD_HDR_DEV_ID_MSK		(0xffff << CMD_HDR_DEV_ID_OFF)315/* dw2 */316#define CMD_HDR_CFL_OFF			0317#define CMD_HDR_CFL_MSK			(0x1ff << CMD_HDR_CFL_OFF)318#define CMD_HDR_NCQ_TAG_OFF		10319#define CMD_HDR_NCQ_TAG_MSK		(0x1f << CMD_HDR_NCQ_TAG_OFF)320#define CMD_HDR_MRFL_OFF		15321#define CMD_HDR_MRFL_MSK		(0x1ff << CMD_HDR_MRFL_OFF)322#define CMD_HDR_SG_MOD_OFF		24323#define CMD_HDR_SG_MOD_MSK		(0x3 << CMD_HDR_SG_MOD_OFF)324#define CMD_HDR_FIRST_BURST_OFF		26325#define CMD_HDR_FIRST_BURST_MSK		(0x1 << CMD_HDR_SG_MOD_OFF)326/* dw3 */327#define CMD_HDR_IPTT_OFF		0328#define CMD_HDR_IPTT_MSK		(0xffff << CMD_HDR_IPTT_OFF)329/* dw6 */330#define CMD_HDR_DIF_SGL_LEN_OFF		0331#define CMD_HDR_DIF_SGL_LEN_MSK		(0xffff << CMD_HDR_DIF_SGL_LEN_OFF)332#define CMD_HDR_DATA_SGL_LEN_OFF	16333#define CMD_HDR_DATA_SGL_LEN_MSK	(0xffff << CMD_HDR_DATA_SGL_LEN_OFF)334#define CMD_HDR_ABORT_IPTT_OFF		16335#define CMD_HDR_ABORT_IPTT_MSK		(0xffff << CMD_HDR_ABORT_IPTT_OFF)336 337/* Completion header */338/* dw0 */339#define CMPLT_HDR_ERR_PHASE_OFF	2340#define CMPLT_HDR_ERR_PHASE_MSK	(0xff << CMPLT_HDR_ERR_PHASE_OFF)341#define CMPLT_HDR_RSPNS_XFRD_OFF	10342#define CMPLT_HDR_RSPNS_XFRD_MSK	(0x1 << CMPLT_HDR_RSPNS_XFRD_OFF)343#define CMPLT_HDR_ERX_OFF		12344#define CMPLT_HDR_ERX_MSK		(0x1 << CMPLT_HDR_ERX_OFF)345#define CMPLT_HDR_ABORT_STAT_OFF	13346#define CMPLT_HDR_ABORT_STAT_MSK	(0x7 << CMPLT_HDR_ABORT_STAT_OFF)347/* abort_stat */348#define STAT_IO_NOT_VALID		0x1349#define STAT_IO_NO_DEVICE		0x2350#define STAT_IO_COMPLETE		0x3351#define STAT_IO_ABORTED			0x4352/* dw1 */353#define CMPLT_HDR_IPTT_OFF		0354#define CMPLT_HDR_IPTT_MSK		(0xffff << CMPLT_HDR_IPTT_OFF)355#define CMPLT_HDR_DEV_ID_OFF		16356#define CMPLT_HDR_DEV_ID_MSK		(0xffff << CMPLT_HDR_DEV_ID_OFF)357 358/* ITCT header */359/* qw0 */360#define ITCT_HDR_DEV_TYPE_OFF		0361#define ITCT_HDR_DEV_TYPE_MSK		(0x3 << ITCT_HDR_DEV_TYPE_OFF)362#define ITCT_HDR_VALID_OFF		2363#define ITCT_HDR_VALID_MSK		(0x1 << ITCT_HDR_VALID_OFF)364#define ITCT_HDR_MCR_OFF		5365#define ITCT_HDR_MCR_MSK		(0xf << ITCT_HDR_MCR_OFF)366#define ITCT_HDR_VLN_OFF		9367#define ITCT_HDR_VLN_MSK		(0xf << ITCT_HDR_VLN_OFF)368#define ITCT_HDR_SMP_TIMEOUT_OFF	16369#define ITCT_HDR_SMP_TIMEOUT_8US	1370#define ITCT_HDR_SMP_TIMEOUT		(ITCT_HDR_SMP_TIMEOUT_8US * \371					 250) /* 2ms */372#define ITCT_HDR_AWT_CONTINUE_OFF	25373#define ITCT_HDR_PORT_ID_OFF		28374#define ITCT_HDR_PORT_ID_MSK		(0xf << ITCT_HDR_PORT_ID_OFF)375/* qw2 */376#define ITCT_HDR_INLT_OFF		0377#define ITCT_HDR_INLT_MSK		(0xffffULL << ITCT_HDR_INLT_OFF)378#define ITCT_HDR_BITLT_OFF		16379#define ITCT_HDR_BITLT_MSK		(0xffffULL << ITCT_HDR_BITLT_OFF)380#define ITCT_HDR_MCTLT_OFF		32381#define ITCT_HDR_MCTLT_MSK		(0xffffULL << ITCT_HDR_MCTLT_OFF)382#define ITCT_HDR_RTOLT_OFF		48383#define ITCT_HDR_RTOLT_MSK		(0xffffULL << ITCT_HDR_RTOLT_OFF)384 385#define HISI_SAS_FATAL_INT_NR	2386 387struct hisi_sas_complete_v2_hdr {388	__le32 dw0;389	__le32 dw1;390	__le32 act;391	__le32 dw3;392};393 394struct hisi_sas_err_record_v2 {395	/* dw0 */396	__le32 trans_tx_fail_type;397 398	/* dw1 */399	__le32 trans_rx_fail_type;400 401	/* dw2 */402	__le16 dma_tx_err_type;403	__le16 sipc_rx_err_type;404 405	/* dw3 */406	__le32 dma_rx_err_type;407};408 409struct signal_attenuation_s {410	u32 de_emphasis;411	u32 preshoot;412	u32 boost;413};414 415struct sig_atten_lu_s {416	const struct signal_attenuation_s *att;417	u32 sas_phy_ctrl;418};419 420static const struct hisi_sas_hw_error one_bit_ecc_errors[] = {421	{422		.irq_msk = BIT(SAS_ECC_INTR_DQE_ECC_1B_OFF),423		.msk = HGC_DQE_ECC_1B_ADDR_MSK,424		.shift = HGC_DQE_ECC_1B_ADDR_OFF,425		.msg = "hgc_dqe_ecc1b_intr",426		.reg = HGC_DQE_ECC_ADDR,427	},428	{429		.irq_msk = BIT(SAS_ECC_INTR_IOST_ECC_1B_OFF),430		.msk = HGC_IOST_ECC_1B_ADDR_MSK,431		.shift = HGC_IOST_ECC_1B_ADDR_OFF,432		.msg = "hgc_iost_ecc1b_intr",433		.reg = HGC_IOST_ECC_ADDR,434	},435	{436		.irq_msk = BIT(SAS_ECC_INTR_ITCT_ECC_1B_OFF),437		.msk = HGC_ITCT_ECC_1B_ADDR_MSK,438		.shift = HGC_ITCT_ECC_1B_ADDR_OFF,439		.msg = "hgc_itct_ecc1b_intr",440		.reg = HGC_ITCT_ECC_ADDR,441	},442	{443		.irq_msk = BIT(SAS_ECC_INTR_IOSTLIST_ECC_1B_OFF),444		.msk = HGC_LM_DFX_STATUS2_IOSTLIST_MSK,445		.shift = HGC_LM_DFX_STATUS2_IOSTLIST_OFF,446		.msg = "hgc_iostl_ecc1b_intr",447		.reg = HGC_LM_DFX_STATUS2,448	},449	{450		.irq_msk = BIT(SAS_ECC_INTR_ITCTLIST_ECC_1B_OFF),451		.msk = HGC_LM_DFX_STATUS2_ITCTLIST_MSK,452		.shift = HGC_LM_DFX_STATUS2_ITCTLIST_OFF,453		.msg = "hgc_itctl_ecc1b_intr",454		.reg = HGC_LM_DFX_STATUS2,455	},456	{457		.irq_msk = BIT(SAS_ECC_INTR_CQE_ECC_1B_OFF),458		.msk = HGC_CQE_ECC_1B_ADDR_MSK,459		.shift = HGC_CQE_ECC_1B_ADDR_OFF,460		.msg = "hgc_cqe_ecc1b_intr",461		.reg = HGC_CQE_ECC_ADDR,462	},463	{464		.irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM0_ECC_1B_OFF),465		.msk = HGC_RXM_DFX_STATUS14_MEM0_MSK,466		.shift = HGC_RXM_DFX_STATUS14_MEM0_OFF,467		.msg = "rxm_mem0_ecc1b_intr",468		.reg = HGC_RXM_DFX_STATUS14,469	},470	{471		.irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM1_ECC_1B_OFF),472		.msk = HGC_RXM_DFX_STATUS14_MEM1_MSK,473		.shift = HGC_RXM_DFX_STATUS14_MEM1_OFF,474		.msg = "rxm_mem1_ecc1b_intr",475		.reg = HGC_RXM_DFX_STATUS14,476	},477	{478		.irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM2_ECC_1B_OFF),479		.msk = HGC_RXM_DFX_STATUS14_MEM2_MSK,480		.shift = HGC_RXM_DFX_STATUS14_MEM2_OFF,481		.msg = "rxm_mem2_ecc1b_intr",482		.reg = HGC_RXM_DFX_STATUS14,483	},484	{485		.irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM3_ECC_1B_OFF),486		.msk = HGC_RXM_DFX_STATUS15_MEM3_MSK,487		.shift = HGC_RXM_DFX_STATUS15_MEM3_OFF,488		.msg = "rxm_mem3_ecc1b_intr",489		.reg = HGC_RXM_DFX_STATUS15,490	},491};492 493static const struct hisi_sas_hw_error multi_bit_ecc_errors[] = {494	{495		.irq_msk = BIT(SAS_ECC_INTR_DQE_ECC_MB_OFF),496		.msk = HGC_DQE_ECC_MB_ADDR_MSK,497		.shift = HGC_DQE_ECC_MB_ADDR_OFF,498		.msg = "hgc_dqe_eccbad_intr",499		.reg = HGC_DQE_ECC_ADDR,500	},501	{502		.irq_msk = BIT(SAS_ECC_INTR_IOST_ECC_MB_OFF),503		.msk = HGC_IOST_ECC_MB_ADDR_MSK,504		.shift = HGC_IOST_ECC_MB_ADDR_OFF,505		.msg = "hgc_iost_eccbad_intr",506		.reg = HGC_IOST_ECC_ADDR,507	},508	{509		.irq_msk = BIT(SAS_ECC_INTR_ITCT_ECC_MB_OFF),510		.msk = HGC_ITCT_ECC_MB_ADDR_MSK,511		.shift = HGC_ITCT_ECC_MB_ADDR_OFF,512		.msg = "hgc_itct_eccbad_intr",513		.reg = HGC_ITCT_ECC_ADDR,514	},515	{516		.irq_msk = BIT(SAS_ECC_INTR_IOSTLIST_ECC_MB_OFF),517		.msk = HGC_LM_DFX_STATUS2_IOSTLIST_MSK,518		.shift = HGC_LM_DFX_STATUS2_IOSTLIST_OFF,519		.msg = "hgc_iostl_eccbad_intr",520		.reg = HGC_LM_DFX_STATUS2,521	},522	{523		.irq_msk = BIT(SAS_ECC_INTR_ITCTLIST_ECC_MB_OFF),524		.msk = HGC_LM_DFX_STATUS2_ITCTLIST_MSK,525		.shift = HGC_LM_DFX_STATUS2_ITCTLIST_OFF,526		.msg = "hgc_itctl_eccbad_intr",527		.reg = HGC_LM_DFX_STATUS2,528	},529	{530		.irq_msk = BIT(SAS_ECC_INTR_CQE_ECC_MB_OFF),531		.msk = HGC_CQE_ECC_MB_ADDR_MSK,532		.shift = HGC_CQE_ECC_MB_ADDR_OFF,533		.msg = "hgc_cqe_eccbad_intr",534		.reg = HGC_CQE_ECC_ADDR,535	},536	{537		.irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM0_ECC_MB_OFF),538		.msk = HGC_RXM_DFX_STATUS14_MEM0_MSK,539		.shift = HGC_RXM_DFX_STATUS14_MEM0_OFF,540		.msg = "rxm_mem0_eccbad_intr",541		.reg = HGC_RXM_DFX_STATUS14,542	},543	{544		.irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM1_ECC_MB_OFF),545		.msk = HGC_RXM_DFX_STATUS14_MEM1_MSK,546		.shift = HGC_RXM_DFX_STATUS14_MEM1_OFF,547		.msg = "rxm_mem1_eccbad_intr",548		.reg = HGC_RXM_DFX_STATUS14,549	},550	{551		.irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM2_ECC_MB_OFF),552		.msk = HGC_RXM_DFX_STATUS14_MEM2_MSK,553		.shift = HGC_RXM_DFX_STATUS14_MEM2_OFF,554		.msg = "rxm_mem2_eccbad_intr",555		.reg = HGC_RXM_DFX_STATUS14,556	},557	{558		.irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM3_ECC_MB_OFF),559		.msk = HGC_RXM_DFX_STATUS15_MEM3_MSK,560		.shift = HGC_RXM_DFX_STATUS15_MEM3_OFF,561		.msg = "rxm_mem3_eccbad_intr",562		.reg = HGC_RXM_DFX_STATUS15,563	},564};565 566enum {567	HISI_SAS_PHY_PHY_UPDOWN,568	HISI_SAS_PHY_CHNL_INT,569	HISI_SAS_PHY_INT_NR570};571 572enum {573	TRANS_TX_FAIL_BASE = 0x0, /* dw0 */574	TRANS_RX_FAIL_BASE = 0x20, /* dw1 */575	DMA_TX_ERR_BASE = 0x40, /* dw2 bit 15-0 */576	SIPC_RX_ERR_BASE = 0x50, /* dw2 bit 31-16*/577	DMA_RX_ERR_BASE = 0x60, /* dw3 */578 579	/* trans tx*/580	TRANS_TX_OPEN_FAIL_WITH_IT_NEXUS_LOSS = TRANS_TX_FAIL_BASE, /* 0x0 */581	TRANS_TX_ERR_PHY_NOT_ENABLE, /* 0x1 */582	TRANS_TX_OPEN_CNX_ERR_WRONG_DESTINATION, /* 0x2 */583	TRANS_TX_OPEN_CNX_ERR_ZONE_VIOLATION, /* 0x3 */584	TRANS_TX_OPEN_CNX_ERR_BY_OTHER, /* 0x4 */585	RESERVED0, /* 0x5 */586	TRANS_TX_OPEN_CNX_ERR_AIP_TIMEOUT, /* 0x6 */587	TRANS_TX_OPEN_CNX_ERR_STP_RESOURCES_BUSY, /* 0x7 */588	TRANS_TX_OPEN_CNX_ERR_PROTOCOL_NOT_SUPPORTED, /* 0x8 */589	TRANS_TX_OPEN_CNX_ERR_CONNECTION_RATE_NOT_SUPPORTED, /* 0x9 */590	TRANS_TX_OPEN_CNX_ERR_BAD_DESTINATION, /* 0xa */591	TRANS_TX_OPEN_CNX_ERR_BREAK_RCVD, /* 0xb */592	TRANS_TX_OPEN_CNX_ERR_LOW_PHY_POWER, /* 0xc */593	TRANS_TX_OPEN_CNX_ERR_PATHWAY_BLOCKED, /* 0xd */594	TRANS_TX_OPEN_CNX_ERR_OPEN_TIMEOUT, /* 0xe */595	TRANS_TX_OPEN_CNX_ERR_NO_DESTINATION, /* 0xf */596	TRANS_TX_OPEN_RETRY_ERR_THRESHOLD_REACHED, /* 0x10 */597	TRANS_TX_ERR_FRAME_TXED, /* 0x11 */598	TRANS_TX_ERR_WITH_BREAK_TIMEOUT, /* 0x12 */599	TRANS_TX_ERR_WITH_BREAK_REQUEST, /* 0x13 */600	TRANS_TX_ERR_WITH_BREAK_RECEVIED, /* 0x14 */601	TRANS_TX_ERR_WITH_CLOSE_TIMEOUT, /* 0x15 */602	TRANS_TX_ERR_WITH_CLOSE_NORMAL, /* 0x16 for ssp*/603	TRANS_TX_ERR_WITH_CLOSE_PHYDISALE, /* 0x17 */604	TRANS_TX_ERR_WITH_CLOSE_DWS_TIMEOUT, /* 0x18 */605	TRANS_TX_ERR_WITH_CLOSE_COMINIT, /* 0x19 */606	TRANS_TX_ERR_WITH_NAK_RECEVIED, /* 0x1a for ssp*/607	TRANS_TX_ERR_WITH_ACK_NAK_TIMEOUT, /* 0x1b for ssp*/608	/*IO_TX_ERR_WITH_R_ERR_RECEVIED, [> 0x1b for sata/stp<] */609	TRANS_TX_ERR_WITH_CREDIT_TIMEOUT, /* 0x1c for ssp */610	/*IO_RX_ERR_WITH_SATA_DEVICE_LOST 0x1c for sata/stp */611	TRANS_TX_ERR_WITH_IPTT_CONFLICT, /* 0x1d for ssp/smp */612	TRANS_TX_ERR_WITH_OPEN_BY_DES_OR_OTHERS, /* 0x1e */613	/*IO_TX_ERR_WITH_SYNC_RXD, [> 0x1e <] for sata/stp */614	TRANS_TX_ERR_WITH_WAIT_RECV_TIMEOUT, /* 0x1f for sata/stp */615 616	/* trans rx */617	TRANS_RX_ERR_WITH_RXFRAME_CRC_ERR = TRANS_RX_FAIL_BASE, /* 0x20 */618	TRANS_RX_ERR_WITH_RXFIS_8B10B_DISP_ERR, /* 0x21 for sata/stp */619	TRANS_RX_ERR_WITH_RXFRAME_HAVE_ERRPRM, /* 0x22 for ssp/smp */620	/*IO_ERR_WITH_RXFIS_8B10B_CODE_ERR, [> 0x22 <] for sata/stp */621	TRANS_RX_ERR_WITH_RXFIS_DECODE_ERROR, /* 0x23 for sata/stp */622	TRANS_RX_ERR_WITH_RXFIS_CRC_ERR, /* 0x24 for sata/stp */623	TRANS_RX_ERR_WITH_RXFRAME_LENGTH_OVERRUN, /* 0x25 for smp */624	/*IO_ERR_WITH_RXFIS_TX SYNCP, [> 0x25 <] for sata/stp */625	TRANS_RX_ERR_WITH_RXFIS_RX_SYNCP, /* 0x26 for sata/stp*/626	TRANS_RX_ERR_WITH_LINK_BUF_OVERRUN, /* 0x27 */627	TRANS_RX_ERR_WITH_BREAK_TIMEOUT, /* 0x28 */628	TRANS_RX_ERR_WITH_BREAK_REQUEST, /* 0x29 */629	TRANS_RX_ERR_WITH_BREAK_RECEVIED, /* 0x2a */630	RESERVED1, /* 0x2b */631	TRANS_RX_ERR_WITH_CLOSE_NORMAL, /* 0x2c */632	TRANS_RX_ERR_WITH_CLOSE_PHY_DISABLE, /* 0x2d */633	TRANS_RX_ERR_WITH_CLOSE_DWS_TIMEOUT, /* 0x2e */634	TRANS_RX_ERR_WITH_CLOSE_COMINIT, /* 0x2f */635	TRANS_RX_ERR_WITH_DATA_LEN0, /* 0x30 for ssp/smp */636	TRANS_RX_ERR_WITH_BAD_HASH, /* 0x31 for ssp */637	/*IO_RX_ERR_WITH_FIS_TOO_SHORT, [> 0x31 <] for sata/stp */638	TRANS_RX_XRDY_WLEN_ZERO_ERR, /* 0x32 for ssp*/639	/*IO_RX_ERR_WITH_FIS_TOO_LONG, [> 0x32 <] for sata/stp */640	TRANS_RX_SSP_FRM_LEN_ERR, /* 0x33 for ssp */641	/*IO_RX_ERR_WITH_SATA_DEVICE_LOST, [> 0x33 <] for sata */642	RESERVED2, /* 0x34 */643	RESERVED3, /* 0x35 */644	RESERVED4, /* 0x36 */645	RESERVED5, /* 0x37 */646	TRANS_RX_ERR_WITH_BAD_FRM_TYPE, /* 0x38 */647	TRANS_RX_SMP_FRM_LEN_ERR, /* 0x39 */648	TRANS_RX_SMP_RESP_TIMEOUT_ERR, /* 0x3a */649	RESERVED6, /* 0x3b */650	RESERVED7, /* 0x3c */651	RESERVED8, /* 0x3d */652	RESERVED9, /* 0x3e */653	TRANS_RX_R_ERR, /* 0x3f */654 655	/* dma tx */656	DMA_TX_DIF_CRC_ERR = DMA_TX_ERR_BASE, /* 0x40 */657	DMA_TX_DIF_APP_ERR, /* 0x41 */658	DMA_TX_DIF_RPP_ERR, /* 0x42 */659	DMA_TX_DATA_SGL_OVERFLOW, /* 0x43 */660	DMA_TX_DIF_SGL_OVERFLOW, /* 0x44 */661	DMA_TX_UNEXP_XFER_ERR, /* 0x45 */662	DMA_TX_UNEXP_RETRANS_ERR, /* 0x46 */663	DMA_TX_XFER_LEN_OVERFLOW, /* 0x47 */664	DMA_TX_XFER_OFFSET_ERR, /* 0x48 */665	DMA_TX_RAM_ECC_ERR, /* 0x49 */666	DMA_TX_DIF_LEN_ALIGN_ERR, /* 0x4a */667	DMA_TX_MAX_ERR_CODE,668 669	/* sipc rx */670	SIPC_RX_FIS_STATUS_ERR_BIT_VLD = SIPC_RX_ERR_BASE, /* 0x50 */671	SIPC_RX_PIO_WRSETUP_STATUS_DRQ_ERR, /* 0x51 */672	SIPC_RX_FIS_STATUS_BSY_BIT_ERR, /* 0x52 */673	SIPC_RX_WRSETUP_LEN_ODD_ERR, /* 0x53 */674	SIPC_RX_WRSETUP_LEN_ZERO_ERR, /* 0x54 */675	SIPC_RX_WRDATA_LEN_NOT_MATCH_ERR, /* 0x55 */676	SIPC_RX_NCQ_WRSETUP_OFFSET_ERR, /* 0x56 */677	SIPC_RX_NCQ_WRSETUP_AUTO_ACTIVE_ERR, /* 0x57 */678	SIPC_RX_SATA_UNEXP_FIS_ERR, /* 0x58 */679	SIPC_RX_WRSETUP_ESTATUS_ERR, /* 0x59 */680	SIPC_RX_DATA_UNDERFLOW_ERR, /* 0x5a */681	SIPC_RX_MAX_ERR_CODE,682 683	/* dma rx */684	DMA_RX_DIF_CRC_ERR = DMA_RX_ERR_BASE, /* 0x60 */685	DMA_RX_DIF_APP_ERR, /* 0x61 */686	DMA_RX_DIF_RPP_ERR, /* 0x62 */687	DMA_RX_DATA_SGL_OVERFLOW, /* 0x63 */688	DMA_RX_DIF_SGL_OVERFLOW, /* 0x64 */689	DMA_RX_DATA_LEN_OVERFLOW, /* 0x65 */690	DMA_RX_DATA_LEN_UNDERFLOW, /* 0x66 */691	DMA_RX_DATA_OFFSET_ERR, /* 0x67 */692	RESERVED10, /* 0x68 */693	DMA_RX_SATA_FRAME_TYPE_ERR, /* 0x69 */694	DMA_RX_RESP_BUF_OVERFLOW, /* 0x6a */695	DMA_RX_UNEXP_RETRANS_RESP_ERR, /* 0x6b */696	DMA_RX_UNEXP_NORM_RESP_ERR, /* 0x6c */697	DMA_RX_UNEXP_RDFRAME_ERR, /* 0x6d */698	DMA_RX_PIO_DATA_LEN_ERR, /* 0x6e */699	DMA_RX_RDSETUP_STATUS_ERR, /* 0x6f */700	DMA_RX_RDSETUP_STATUS_DRQ_ERR, /* 0x70 */701	DMA_RX_RDSETUP_STATUS_BSY_ERR, /* 0x71 */702	DMA_RX_RDSETUP_LEN_ODD_ERR, /* 0x72 */703	DMA_RX_RDSETUP_LEN_ZERO_ERR, /* 0x73 */704	DMA_RX_RDSETUP_LEN_OVER_ERR, /* 0x74 */705	DMA_RX_RDSETUP_OFFSET_ERR, /* 0x75 */706	DMA_RX_RDSETUP_ACTIVE_ERR, /* 0x76 */707	DMA_RX_RDSETUP_ESTATUS_ERR, /* 0x77 */708	DMA_RX_RAM_ECC_ERR, /* 0x78 */709	DMA_RX_UNKNOWN_FRM_ERR, /* 0x79 */710	DMA_RX_MAX_ERR_CODE,711};712 713#define HISI_SAS_COMMAND_ENTRIES_V2_HW 4096714#define HISI_MAX_SATA_SUPPORT_V2_HW	(HISI_SAS_COMMAND_ENTRIES_V2_HW/64 - 1)715 716#define DIR_NO_DATA 0717#define DIR_TO_INI 1718#define DIR_TO_DEVICE 2719#define DIR_RESERVED 3720 721#define ERR_ON_TX_PHASE(err_phase) (err_phase == 0x2 || \722		err_phase == 0x4 || err_phase == 0x8 ||\723		err_phase == 0x6 || err_phase == 0xa)724#define ERR_ON_RX_PHASE(err_phase) (err_phase == 0x10 || \725		err_phase == 0x20 || err_phase == 0x40)726 727static void link_timeout_disable_link(struct timer_list *t);728 729static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off)730{731	void __iomem *regs = hisi_hba->regs + off;732 733	return readl(regs);734}735 736static u32 hisi_sas_read32_relaxed(struct hisi_hba *hisi_hba, u32 off)737{738	void __iomem *regs = hisi_hba->regs + off;739 740	return readl_relaxed(regs);741}742 743static void hisi_sas_write32(struct hisi_hba *hisi_hba, u32 off, u32 val)744{745	void __iomem *regs = hisi_hba->regs + off;746 747	writel(val, regs);748}749 750static void hisi_sas_phy_write32(struct hisi_hba *hisi_hba, int phy_no,751				 u32 off, u32 val)752{753	void __iomem *regs = hisi_hba->regs + (0x400 * phy_no) + off;754 755	writel(val, regs);756}757 758static u32 hisi_sas_phy_read32(struct hisi_hba *hisi_hba,759				      int phy_no, u32 off)760{761	void __iomem *regs = hisi_hba->regs + (0x400 * phy_no) + off;762 763	return readl(regs);764}765 766/* This function needs to be protected from pre-emption. */767static int768slot_index_alloc_quirk_v2_hw(struct hisi_hba *hisi_hba,769			     struct domain_device *device)770{771	int sata_dev = dev_is_sata(device);772	void *bitmap = hisi_hba->slot_index_tags;773	struct hisi_sas_device *sas_dev = device->lldd_dev;774	int sata_idx = sas_dev->sata_idx;775	int start, end;776 777	if (!sata_dev) {778		/*779		 * STP link SoC bug workaround: index starts from 1.780		 * additionally, we can only allocate odd IPTT(1~4095)781		 * for SAS/SMP device.782		 */783		start = 1;784		end = hisi_hba->slot_index_count;785	} else {786		if (sata_idx >= HISI_MAX_SATA_SUPPORT_V2_HW)787			return -EINVAL;788 789		/*790		 * For SATA device: allocate even IPTT in this interval791		 * [64*(sata_idx+1), 64*(sata_idx+2)], then each SATA device792		 * own 32 IPTTs. IPTT 0 shall not be used duing to STP link793		 * SoC bug workaround. So we ignore the first 32 even IPTTs.794		 */795		start = 64 * (sata_idx + 1);796		end = 64 * (sata_idx + 2);797	}798 799	spin_lock(&hisi_hba->lock);800	while (1) {801		start = find_next_zero_bit(bitmap,802					hisi_hba->slot_index_count, start);803		if (start >= end) {804			spin_unlock(&hisi_hba->lock);805			return -SAS_QUEUE_FULL;806		}807		/*808		 * SAS IPTT bit0 should be 1, and SATA IPTT bit0 should be 0.809		 */810		if (sata_dev ^ (start & 1))811			break;812		start++;813	}814 815	set_bit(start, bitmap);816	spin_unlock(&hisi_hba->lock);817	return start;818}819 820static bool sata_index_alloc_v2_hw(struct hisi_hba *hisi_hba, int *idx)821{822	unsigned int index;823	struct device *dev = hisi_hba->dev;824	void *bitmap = hisi_hba->sata_dev_bitmap;825 826	index = find_first_zero_bit(bitmap, HISI_MAX_SATA_SUPPORT_V2_HW);827	if (index >= HISI_MAX_SATA_SUPPORT_V2_HW) {828		dev_warn(dev, "alloc sata index failed, index=%d\n", index);829		return false;830	}831 832	set_bit(index, bitmap);833	*idx = index;834	return true;835}836 837 838static struct839hisi_sas_device *alloc_dev_quirk_v2_hw(struct domain_device *device)840{841	struct hisi_hba *hisi_hba = device->port->ha->lldd_ha;842	struct hisi_sas_device *sas_dev = NULL;843	int i, sata_dev = dev_is_sata(device);844	int sata_idx = -1;845 846	spin_lock(&hisi_hba->lock);847 848	if (sata_dev)849		if (!sata_index_alloc_v2_hw(hisi_hba, &sata_idx))850			goto out;851 852	for (i = 0; i < HISI_SAS_MAX_DEVICES; i++) {853		/*854		 * SATA device id bit0 should be 0855		 */856		if (sata_dev && (i & 1))857			continue;858		if (hisi_hba->devices[i].dev_type == SAS_PHY_UNUSED) {859			int queue = i % hisi_hba->queue_count;860			struct hisi_sas_dq *dq = &hisi_hba->dq[queue];861 862			hisi_hba->devices[i].device_id = i;863			sas_dev = &hisi_hba->devices[i];864			sas_dev->dev_status = HISI_SAS_DEV_INIT;865			sas_dev->dev_type = device->dev_type;866			sas_dev->hisi_hba = hisi_hba;867			sas_dev->sas_device = device;868			sas_dev->sata_idx = sata_idx;869			sas_dev->dq = dq;870			spin_lock_init(&sas_dev->lock);871			INIT_LIST_HEAD(&hisi_hba->devices[i].list);872			break;873		}874	}875 876out:877	spin_unlock(&hisi_hba->lock);878 879	return sas_dev;880}881 882static void config_phy_opt_mode_v2_hw(struct hisi_hba *hisi_hba, int phy_no)883{884	u32 cfg = hisi_sas_phy_read32(hisi_hba, phy_no, PHY_CFG);885 886	cfg &= ~PHY_CFG_DC_OPT_MSK;887	cfg |= 1 << PHY_CFG_DC_OPT_OFF;888	hisi_sas_phy_write32(hisi_hba, phy_no, PHY_CFG, cfg);889}890 891static void config_id_frame_v2_hw(struct hisi_hba *hisi_hba, int phy_no)892{893	struct sas_identify_frame identify_frame;894	u32 *identify_buffer;895 896	memset(&identify_frame, 0, sizeof(identify_frame));897	identify_frame.dev_type = SAS_END_DEVICE;898	identify_frame.frame_type = 0;899	identify_frame._un1 = 1;900	identify_frame.initiator_bits = SAS_PROTOCOL_ALL;901	identify_frame.target_bits = SAS_PROTOCOL_NONE;902	memcpy(&identify_frame._un4_11[0], hisi_hba->sas_addr, SAS_ADDR_SIZE);903	memcpy(&identify_frame.sas_addr[0], hisi_hba->sas_addr,	SAS_ADDR_SIZE);904	identify_frame.phy_id = phy_no;905	identify_buffer = (u32 *)(&identify_frame);906 907	hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD0,908			__swab32(identify_buffer[0]));909	hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD1,910			__swab32(identify_buffer[1]));911	hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD2,912			__swab32(identify_buffer[2]));913	hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD3,914			__swab32(identify_buffer[3]));915	hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD4,916			__swab32(identify_buffer[4]));917	hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD5,918			__swab32(identify_buffer[5]));919}920 921static void setup_itct_v2_hw(struct hisi_hba *hisi_hba,922			     struct hisi_sas_device *sas_dev)923{924	struct domain_device *device = sas_dev->sas_device;925	struct device *dev = hisi_hba->dev;926	u64 qw0, device_id = sas_dev->device_id;927	struct hisi_sas_itct *itct = &hisi_hba->itct[device_id];928	struct domain_device *parent_dev = device->parent;929	struct asd_sas_port *sas_port = device->port;930	struct hisi_sas_port *port = to_hisi_sas_port(sas_port);931	u64 sas_addr;932 933	memset(itct, 0, sizeof(*itct));934 935	/* qw0 */936	qw0 = 0;937	switch (sas_dev->dev_type) {938	case SAS_END_DEVICE:939	case SAS_EDGE_EXPANDER_DEVICE:940	case SAS_FANOUT_EXPANDER_DEVICE:941		qw0 = HISI_SAS_DEV_TYPE_SSP << ITCT_HDR_DEV_TYPE_OFF;942		break;943	case SAS_SATA_DEV:944	case SAS_SATA_PENDING:945		if (parent_dev && dev_is_expander(parent_dev->dev_type))946			qw0 = HISI_SAS_DEV_TYPE_STP << ITCT_HDR_DEV_TYPE_OFF;947		else948			qw0 = HISI_SAS_DEV_TYPE_SATA << ITCT_HDR_DEV_TYPE_OFF;949		break;950	default:951		dev_warn(dev, "setup itct: unsupported dev type (%d)\n",952			 sas_dev->dev_type);953	}954 955	qw0 |= ((1 << ITCT_HDR_VALID_OFF) |956		(device->linkrate << ITCT_HDR_MCR_OFF) |957		(1 << ITCT_HDR_VLN_OFF) |958		(ITCT_HDR_SMP_TIMEOUT << ITCT_HDR_SMP_TIMEOUT_OFF) |959		(1 << ITCT_HDR_AWT_CONTINUE_OFF) |960		(port->id << ITCT_HDR_PORT_ID_OFF));961	itct->qw0 = cpu_to_le64(qw0);962 963	/* qw1 */964	memcpy(&sas_addr, device->sas_addr, SAS_ADDR_SIZE);965	itct->sas_addr = cpu_to_le64(__swab64(sas_addr));966 967	/* qw2 */968	if (!dev_is_sata(device))969		itct->qw2 = cpu_to_le64((5000ULL << ITCT_HDR_INLT_OFF) |970					(0x1ULL << ITCT_HDR_BITLT_OFF) |971					(0x32ULL << ITCT_HDR_MCTLT_OFF) |972					(0x1ULL << ITCT_HDR_RTOLT_OFF));973}974 975static int clear_itct_v2_hw(struct hisi_hba *hisi_hba,976			    struct hisi_sas_device *sas_dev)977{978	DECLARE_COMPLETION_ONSTACK(completion);979	u64 dev_id = sas_dev->device_id;980	struct hisi_sas_itct *itct = &hisi_hba->itct[dev_id];981	u32 reg_val = hisi_sas_read32(hisi_hba, ENT_INT_SRC3);982	struct device *dev = hisi_hba->dev;983	int i;984 985	sas_dev->completion = &completion;986 987	/* clear the itct interrupt state */988	if (ENT_INT_SRC3_ITC_INT_MSK & reg_val)989		hisi_sas_write32(hisi_hba, ENT_INT_SRC3,990				 ENT_INT_SRC3_ITC_INT_MSK);991 992	/* need to set register twice to clear ITCT for v2 hw */993	for (i = 0; i < 2; i++) {994		reg_val = ITCT_CLR_EN_MSK | (dev_id & ITCT_DEV_MSK);995		hisi_sas_write32(hisi_hba, ITCT_CLR, reg_val);996		if (!wait_for_completion_timeout(sas_dev->completion,997						 HISI_SAS_CLEAR_ITCT_TIMEOUT)) {998			dev_warn(dev, "failed to clear ITCT\n");999			return -ETIMEDOUT;1000		}1001 1002		memset(itct, 0, sizeof(struct hisi_sas_itct));1003	}1004	return 0;1005}1006 1007static void free_device_v2_hw(struct hisi_sas_device *sas_dev)1008{1009	struct hisi_hba *hisi_hba = sas_dev->hisi_hba;1010 1011	/* SoC bug workaround */1012	if (dev_is_sata(sas_dev->sas_device))1013		clear_bit(sas_dev->sata_idx, hisi_hba->sata_dev_bitmap);1014}1015 1016static int reset_hw_v2_hw(struct hisi_hba *hisi_hba)1017{1018	int i, reset_val;1019	u32 val;1020	unsigned long end_time;1021	struct device *dev = hisi_hba->dev;1022 1023	/* The mask needs to be set depending on the number of phys */1024	if (hisi_hba->n_phy == 9)1025		reset_val = 0x1fffff;1026	else1027		reset_val = 0x7ffff;1028 1029	hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, 0);1030 1031	/* Disable all of the PHYs */1032	for (i = 0; i < hisi_hba->n_phy; i++) {1033		u32 phy_cfg = hisi_sas_phy_read32(hisi_hba, i, PHY_CFG);1034 1035		phy_cfg &= ~PHY_CTRL_RESET_MSK;1036		hisi_sas_phy_write32(hisi_hba, i, PHY_CFG, phy_cfg);1037	}1038	udelay(50);1039 1040	/* Ensure DMA tx & rx idle */1041	for (i = 0; i < hisi_hba->n_phy; i++) {1042		u32 dma_tx_status, dma_rx_status;1043 1044		end_time = jiffies + msecs_to_jiffies(1000);1045 1046		while (1) {1047			dma_tx_status = hisi_sas_phy_read32(hisi_hba, i,1048							    DMA_TX_STATUS);1049			dma_rx_status = hisi_sas_phy_read32(hisi_hba, i,1050							    DMA_RX_STATUS);1051 1052			if (!(dma_tx_status & DMA_TX_STATUS_BUSY_MSK) &&1053				!(dma_rx_status & DMA_RX_STATUS_BUSY_MSK))1054				break;1055 1056			msleep(20);1057			if (time_after(jiffies, end_time))1058				return -EIO;1059		}1060	}1061 1062	/* Ensure axi bus idle */1063	end_time = jiffies + msecs_to_jiffies(1000);1064	while (1) {1065		u32 axi_status =1066			hisi_sas_read32(hisi_hba, AXI_CFG);1067 1068		if (axi_status == 0)1069			break;1070 1071		msleep(20);1072		if (time_after(jiffies, end_time))1073			return -EIO;1074	}1075 1076	if (ACPI_HANDLE(dev)) {1077		acpi_status s;1078 1079		s = acpi_evaluate_object(ACPI_HANDLE(dev), "_RST", NULL, NULL);1080		if (ACPI_FAILURE(s)) {1081			dev_err(dev, "Reset failed\n");1082			return -EIO;1083		}1084	} else if (hisi_hba->ctrl) {1085		/* reset and disable clock*/1086		regmap_write(hisi_hba->ctrl, hisi_hba->ctrl_reset_reg,1087				reset_val);1088		regmap_write(hisi_hba->ctrl, hisi_hba->ctrl_clock_ena_reg + 4,1089				reset_val);1090		msleep(1);1091		regmap_read(hisi_hba->ctrl, hisi_hba->ctrl_reset_sts_reg, &val);1092		if (reset_val != (val & reset_val)) {1093			dev_err(dev, "SAS reset fail.\n");1094			return -EIO;1095		}1096 1097		/* De-reset and enable clock*/1098		regmap_write(hisi_hba->ctrl, hisi_hba->ctrl_reset_reg + 4,1099				reset_val);1100		regmap_write(hisi_hba->ctrl, hisi_hba->ctrl_clock_ena_reg,1101				reset_val);1102		msleep(1);1103		regmap_read(hisi_hba->ctrl, hisi_hba->ctrl_reset_sts_reg,1104				&val);1105		if (val & reset_val) {1106			dev_err(dev, "SAS de-reset fail.\n");1107			return -EIO;1108		}1109	} else {1110		dev_err(dev, "no reset method\n");1111		return -EINVAL;1112	}1113 1114	return 0;1115}1116 1117/* This function needs to be called after resetting SAS controller. */1118static void phys_reject_stp_links_v2_hw(struct hisi_hba *hisi_hba)1119{1120	u32 cfg;1121	int phy_no;1122 1123	hisi_hba->reject_stp_links_msk = (1 << hisi_hba->n_phy) - 1;1124	for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) {1125		cfg = hisi_sas_phy_read32(hisi_hba, phy_no, CON_CONTROL);1126		if (!(cfg & CON_CONTROL_CFG_OPEN_ACC_STP_MSK))1127			continue;1128 1129		cfg &= ~CON_CONTROL_CFG_OPEN_ACC_STP_MSK;1130		hisi_sas_phy_write32(hisi_hba, phy_no, CON_CONTROL, cfg);1131	}1132}1133 1134static void phys_try_accept_stp_links_v2_hw(struct hisi_hba *hisi_hba)1135{1136	int phy_no;1137	u32 dma_tx_dfx1;1138 1139	for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) {1140		if (!(hisi_hba->reject_stp_links_msk & BIT(phy_no)))1141			continue;1142 1143		dma_tx_dfx1 = hisi_sas_phy_read32(hisi_hba, phy_no,1144						DMA_TX_DFX1);1145		if (dma_tx_dfx1 & DMA_TX_DFX1_IPTT_MSK) {1146			u32 cfg = hisi_sas_phy_read32(hisi_hba,1147				phy_no, CON_CONTROL);1148 1149			cfg |= CON_CONTROL_CFG_OPEN_ACC_STP_MSK;1150			hisi_sas_phy_write32(hisi_hba, phy_no,1151				CON_CONTROL, cfg);1152			clear_bit(phy_no, &hisi_hba->reject_stp_links_msk);1153		}1154	}1155}1156 1157static const struct signal_attenuation_s x6000 = {9200, 0, 10476};1158static const struct sig_atten_lu_s sig_atten_lu[] = {1159	{ &x6000, 0x3016a68 },1160};1161 1162static void init_reg_v2_hw(struct hisi_hba *hisi_hba)1163{1164	struct device *dev = hisi_hba->dev;1165	u32 sas_phy_ctrl = 0x30b9908;1166	u32 signal[3];1167	int i;1168 1169	/* Global registers init */1170 1171	/* Deal with am-max-transmissions quirk */1172	if (device_property_present(dev, "hip06-sas-v2-quirk-amt")) {1173		hisi_sas_write32(hisi_hba, AM_CFG_MAX_TRANS, 0x2020);1174		hisi_sas_write32(hisi_hba, AM_CFG_SINGLE_PORT_MAX_TRANS,1175				 0x2020);1176	} /* Else, use defaults -> do nothing */1177 1178	hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE,1179			 (u32)((1ULL << hisi_hba->queue_count) - 1));1180	hisi_sas_write32(hisi_hba, AXI_USER1, 0xc0000000);1181	hisi_sas_write32(hisi_hba, AXI_USER2, 0x10000);1182	hisi_sas_write32(hisi_hba, HGC_SAS_TXFAIL_RETRY_CTRL, 0x0);1183	hisi_sas_write32(hisi_hba, HGC_SAS_TX_OPEN_FAIL_RETRY_CTRL, 0x7FF);1184	hisi_sas_write32(hisi_hba, OPENA_WT_CONTI_TIME, 0x1);1185	hisi_sas_write32(hisi_hba, I_T_NEXUS_LOSS_TIME, 0x1F4);1186	hisi_sas_write32(hisi_hba, MAX_CON_TIME_LIMIT_TIME, 0x32);1187	hisi_sas_write32(hisi_hba, BUS_INACTIVE_LIMIT_TIME, 0x1);1188	hisi_sas_write32(hisi_hba, CFG_AGING_TIME, 0x1);1189	hisi_sas_write32(hisi_hba, HGC_ERR_STAT_EN, 0x1);1190	hisi_sas_write32(hisi_hba, HGC_GET_ITV_TIME, 0x1);1191	hisi_sas_write32(hisi_hba, INT_COAL_EN, 0xc);1192	hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, 0x60);1193	hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, 0x3);1194	hisi_sas_write32(hisi_hba, ENT_INT_COAL_TIME, 0x1);1195	hisi_sas_write32(hisi_hba, ENT_INT_COAL_CNT, 0x1);1196	hisi_sas_write32(hisi_hba, OQ_INT_SRC, 0x0);1197	hisi_sas_write32(hisi_hba, ENT_INT_SRC1, 0xffffffff);1198	hisi_sas_write32(hisi_hba, ENT_INT_SRC2, 0xffffffff);1199	hisi_sas_write32(hisi_hba, ENT_INT_SRC3, 0xffffffff);1200	hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, 0x7efefefe);1201	hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK2, 0x7efefefe);1202	hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0x7ffe20fe);1203	hisi_sas_write32(hisi_hba, SAS_ECC_INTR_MSK, 0xfff00c30);1204	for (i = 0; i < hisi_hba->queue_count; i++)1205		hisi_sas_write32(hisi_hba, OQ0_INT_SRC_MSK + 0x4 * i, 0);1206 1207	hisi_sas_write32(hisi_hba, AXI_AHB_CLK_CFG, 1);1208	hisi_sas_write32(hisi_hba, HYPER_STREAM_ID_EN_CFG, 1);1209 1210	/* Get sas_phy_ctrl value to deal with TX FFE issue. */1211	if (!device_property_read_u32_array(dev, "hisilicon,signal-attenuation",1212					    signal, ARRAY_SIZE(signal))) {1213		for (i = 0; i < ARRAY_SIZE(sig_atten_lu); i++) {1214			const struct sig_atten_lu_s *lookup = &sig_atten_lu[i];1215			const struct signal_attenuation_s *att = lookup->att;1216 1217			if ((signal[0] == att->de_emphasis) &&1218			    (signal[1] == att->preshoot) &&1219			    (signal[2] == att->boost)) {1220				sas_phy_ctrl = lookup->sas_phy_ctrl;1221				break;1222			}1223		}1224 1225		if (i == ARRAY_SIZE(sig_atten_lu))1226			dev_warn(dev, "unknown signal attenuation values, using default PHY ctrl config\n");1227	}1228 1229	for (i = 0; i < hisi_hba->n_phy; i++) {1230		struct hisi_sas_phy *phy = &hisi_hba->phy[i];1231		struct asd_sas_phy *sas_phy = &phy->sas_phy;1232		u32 prog_phy_link_rate = 0x800;1233 1234		if (!sas_phy->phy || (sas_phy->phy->maximum_linkrate <1235				SAS_LINK_RATE_1_5_GBPS)) {1236			prog_phy_link_rate = 0x855;1237		} else {1238			enum sas_linkrate max = sas_phy->phy->maximum_linkrate;1239 1240			prog_phy_link_rate =1241				hisi_sas_get_prog_phy_linkrate_mask(max) |1242				0x800;1243		}1244		hisi_sas_phy_write32(hisi_hba, i, PROG_PHY_LINK_RATE,1245			prog_phy_link_rate);1246		hisi_sas_phy_write32(hisi_hba, i, SAS_PHY_CTRL, sas_phy_ctrl);1247		hisi_sas_phy_write32(hisi_hba, i, SL_TOUT_CFG, 0x7d7d7d7d);1248		hisi_sas_phy_write32(hisi_hba, i, SL_CONTROL, 0x0);1249		hisi_sas_phy_write32(hisi_hba, i, TXID_AUTO, 0x2);1250		hisi_sas_phy_write32(hisi_hba, i, DONE_RECEIVED_TIME, 0x8);1251		hisi_sas_phy_write32(hisi_hba, i, CHL_INT0, 0xffffffff);1252		hisi_sas_phy_write32(hisi_hba, i, CHL_INT1, 0xffffffff);1253		hisi_sas_phy_write32(hisi_hba, i, CHL_INT2, 0xfff87fff);1254		hisi_sas_phy_write32(hisi_hba, i, RXOP_CHECK_CFG_H, 0x1000);1255		hisi_sas_phy_write32(hisi_hba, i, CHL_INT1_MSK, 0xff857fff);1256		hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0x8ffffbfe);1257		hisi_sas_phy_write32(hisi_hba, i, SL_CFG, 0x13f801fc);1258		hisi_sas_phy_write32(hisi_hba, i, PHY_CTRL_RDY_MSK, 0x0);1259		hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_NOT_RDY_MSK, 0x0);1260		hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_DWS_RESET_MSK, 0x0);1261		hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_PHY_ENA_MSK, 0x0);1262		hisi_sas_phy_write32(hisi_hba, i, SL_RX_BCAST_CHK_MSK, 0x0);1263		hisi_sas_phy_write32(hisi_hba, i, CHL_INT_COAL_EN, 0x0);1264		hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_OOB_RESTART_MSK, 0x0);1265		if (hisi_hba->refclk_frequency_mhz == 66)1266			hisi_sas_phy_write32(hisi_hba, i, PHY_CTRL, 0x199B694);1267		/* else, do nothing -> leave it how you found it */1268	}1269 1270	for (i = 0; i < hisi_hba->queue_count; i++) {1271		/* Delivery queue */1272		hisi_sas_write32(hisi_hba,1273				 DLVRY_Q_0_BASE_ADDR_HI + (i * 0x14),1274				 upper_32_bits(hisi_hba->cmd_hdr_dma[i]));1275 1276		hisi_sas_write32(hisi_hba, DLVRY_Q_0_BASE_ADDR_LO + (i * 0x14),1277				 lower_32_bits(hisi_hba->cmd_hdr_dma[i]));1278 1279		hisi_sas_write32(hisi_hba, DLVRY_Q_0_DEPTH + (i * 0x14),1280				 HISI_SAS_QUEUE_SLOTS);1281 1282		/* Completion queue */1283		hisi_sas_write32(hisi_hba, COMPL_Q_0_BASE_ADDR_HI + (i * 0x14),1284				 upper_32_bits(hisi_hba->complete_hdr_dma[i]));1285 1286		hisi_sas_write32(hisi_hba, COMPL_Q_0_BASE_ADDR_LO + (i * 0x14),1287				 lower_32_bits(hisi_hba->complete_hdr_dma[i]));1288 1289		hisi_sas_write32(hisi_hba, COMPL_Q_0_DEPTH + (i * 0x14),1290				 HISI_SAS_QUEUE_SLOTS);1291	}1292 1293	/* itct */1294	hisi_sas_write32(hisi_hba, ITCT_BASE_ADDR_LO,1295			 lower_32_bits(hisi_hba->itct_dma));1296 1297	hisi_sas_write32(hisi_hba, ITCT_BASE_ADDR_HI,1298			 upper_32_bits(hisi_hba->itct_dma));1299 1300	/* iost */1301	hisi_sas_write32(hisi_hba, IOST_BASE_ADDR_LO,1302			 lower_32_bits(hisi_hba->iost_dma));1303 1304	hisi_sas_write32(hisi_hba, IOST_BASE_ADDR_HI,1305			 upper_32_bits(hisi_hba->iost_dma));1306 1307	/* breakpoint */1308	hisi_sas_write32(hisi_hba, IO_BROKEN_MSG_ADDR_LO,1309			 lower_32_bits(hisi_hba->breakpoint_dma));1310 1311	hisi_sas_write32(hisi_hba, IO_BROKEN_MSG_ADDR_HI,1312			 upper_32_bits(hisi_hba->breakpoint_dma));1313 1314	/* SATA broken msg */1315	hisi_sas_write32(hisi_hba, IO_SATA_BROKEN_MSG_ADDR_LO,1316			 lower_32_bits(hisi_hba->sata_breakpoint_dma));1317 1318	hisi_sas_write32(hisi_hba, IO_SATA_BROKEN_MSG_ADDR_HI,1319			 upper_32_bits(hisi_hba->sata_breakpoint_dma));1320 1321	/* SATA initial fis */1322	hisi_sas_write32(hisi_hba, SATA_INITI_D2H_STORE_ADDR_LO,1323			 lower_32_bits(hisi_hba->initial_fis_dma));1324 1325	hisi_sas_write32(hisi_hba, SATA_INITI_D2H_STORE_ADDR_HI,1326			 upper_32_bits(hisi_hba->initial_fis_dma));1327}1328 1329static void link_timeout_enable_link(struct timer_list *t)1330{1331	struct hisi_hba *hisi_hba = from_timer(hisi_hba, t, timer);1332	int i, reg_val;1333 1334	for (i = 0; i < hisi_hba->n_phy; i++) {1335		if (hisi_hba->reject_stp_links_msk & BIT(i))1336			continue;1337 1338		reg_val = hisi_sas_phy_read32(hisi_hba, i, CON_CONTROL);1339		if (!(reg_val & BIT(0))) {1340			hisi_sas_phy_write32(hisi_hba, i,1341					CON_CONTROL, 0x7);1342			break;1343		}1344	}1345 1346	hisi_hba->timer.function = link_timeout_disable_link;1347	mod_timer(&hisi_hba->timer, jiffies + msecs_to_jiffies(900));1348}1349 1350static void link_timeout_disable_link(struct timer_list *t)1351{1352	struct hisi_hba *hisi_hba = from_timer(hisi_hba, t, timer);1353	int i, reg_val;1354 1355	reg_val = hisi_sas_read32(hisi_hba, PHY_STATE);1356	for (i = 0; i < hisi_hba->n_phy && reg_val; i++) {1357		if (hisi_hba->reject_stp_links_msk & BIT(i))1358			continue;1359 1360		if (reg_val & BIT(i)) {1361			hisi_sas_phy_write32(hisi_hba, i,1362					CON_CONTROL, 0x6);1363			break;1364		}1365	}1366 1367	hisi_hba->timer.function = link_timeout_enable_link;1368	mod_timer(&hisi_hba->timer, jiffies + msecs_to_jiffies(100));1369}1370 1371static void set_link_timer_quirk(struct hisi_hba *hisi_hba)1372{1373	hisi_hba->timer.function = link_timeout_disable_link;1374	hisi_hba->timer.expires = jiffies + msecs_to_jiffies(1000);1375	add_timer(&hisi_hba->timer);1376}1377 1378static int hw_init_v2_hw(struct hisi_hba *hisi_hba)1379{1380	struct device *dev = hisi_hba->dev;1381	int rc;1382 1383	rc = reset_hw_v2_hw(hisi_hba);1384	if (rc) {1385		dev_err(dev, "hisi_sas_reset_hw failed, rc=%d\n", rc);1386		return rc;1387	}1388 1389	msleep(100);1390	init_reg_v2_hw(hisi_hba);1391 1392	return 0;1393}1394 1395static void enable_phy_v2_hw(struct hisi_hba *hisi_hba, int phy_no)1396{1397	u32 cfg = hisi_sas_phy_read32(hisi_hba, phy_no, PHY_CFG);1398 1399	cfg |= PHY_CFG_ENA_MSK;1400	hisi_sas_phy_write32(hisi_hba, phy_no, PHY_CFG, cfg);1401}1402 1403static bool is_sata_phy_v2_hw(struct hisi_hba *hisi_hba, int phy_no)1404{1405	u32 context;1406 1407	context = hisi_sas_read32(hisi_hba, PHY_CONTEXT);1408	if (context & (1 << phy_no))1409		return true;1410 1411	return false;1412}1413 1414static bool tx_fifo_is_empty_v2_hw(struct hisi_hba *hisi_hba, int phy_no)1415{1416	u32 dfx_val;1417 1418	dfx_val = hisi_sas_phy_read32(hisi_hba, phy_no, DMA_TX_DFX1);1419 1420	if (dfx_val & BIT(16))1421		return false;1422 1423	return true;1424}1425 1426static bool axi_bus_is_idle_v2_hw(struct hisi_hba *hisi_hba, int phy_no)1427{1428	int i, max_loop = 1000;1429	struct device *dev = hisi_hba->dev;1430	u32 status, axi_status, dfx_val, dfx_tx_val;1431 1432	for (i = 0; i < max_loop; i++) {1433		status = hisi_sas_read32_relaxed(hisi_hba,1434			AXI_MASTER_CFG_BASE + AM_CURR_TRANS_RETURN);1435 1436		axi_status = hisi_sas_read32(hisi_hba, AXI_CFG);1437		dfx_val = hisi_sas_phy_read32(hisi_hba, phy_no, DMA_TX_DFX1);1438		dfx_tx_val = hisi_sas_phy_read32(hisi_hba,1439			phy_no, DMA_TX_FIFO_DFX0);1440 1441		if ((status == 0x3) && (axi_status == 0x0) &&1442		    (dfx_val & BIT(20)) && (dfx_tx_val & BIT(10)))1443			return true;1444		udelay(10);1445	}1446	dev_err(dev, "bus is not idle phy%d, axi150:0x%x axi100:0x%x port204:0x%x port240:0x%x\n",1447			phy_no, status, axi_status,1448			dfx_val, dfx_tx_val);1449	return false;1450}1451 1452static bool wait_io_done_v2_hw(struct hisi_hba *hisi_hba, int phy_no)1453{1454	int i, max_loop = 1000;1455	struct device *dev = hisi_hba->dev;1456	u32 status, tx_dfx0;1457 1458	for (i = 0; i < max_loop; i++) {1459		status = hisi_sas_phy_read32(hisi_hba, phy_no, LINK_DFX2);1460		status = (status & 0x3fc0) >> 6;1461 1462		if (status != 0x1)1463			return true;1464 1465		tx_dfx0 = hisi_sas_phy_read32(hisi_hba, phy_no, DMA_TX_DFX0);1466		if ((tx_dfx0 & 0x1ff) == 0x2)1467			return true;1468		udelay(10);1469	}1470	dev_err(dev, "IO not done phy%d, port264:0x%x port200:0x%x\n",1471			phy_no, status, tx_dfx0);1472	return false;1473}1474 1475static bool allowed_disable_phy_v2_hw(struct hisi_hba *hisi_hba, int phy_no)1476{1477	if (tx_fifo_is_empty_v2_hw(hisi_hba, phy_no))1478		return true;1479 1480	if (!axi_bus_is_idle_v2_hw(hisi_hba, phy_no))1481		return false;1482 1483	if (!wait_io_done_v2_hw(hisi_hba, phy_no))1484		return false;1485 1486	return true;1487}1488 1489 1490static void disable_phy_v2_hw(struct hisi_hba *hisi_hba, int phy_no)1491{1492	u32 cfg, axi_val, dfx0_val, txid_auto;1493	struct device *dev = hisi_hba->dev;1494 1495	/* Close axi bus. */1496	axi_val = hisi_sas_read32(hisi_hba, AXI_MASTER_CFG_BASE +1497				AM_CTRL_GLOBAL);1498	axi_val |= 0x1;1499	hisi_sas_write32(hisi_hba, AXI_MASTER_CFG_BASE +1500		AM_CTRL_GLOBAL, axi_val);1501 1502	if (is_sata_phy_v2_hw(hisi_hba, phy_no)) {1503		if (allowed_disable_phy_v2_hw(hisi_hba, phy_no))1504			goto do_disable;1505 1506		/* Reset host controller. */1507		queue_work(hisi_hba->wq, &hisi_hba->rst_work);1508		return;1509	}1510 1511	dfx0_val = hisi_sas_phy_read32(hisi_hba, phy_no, PORT_DFX0);1512	dfx0_val = (dfx0_val & 0x1fc0) >> 6;1513	if (dfx0_val != 0x4)1514		goto do_disable;1515 1516	if (!tx_fifo_is_empty_v2_hw(hisi_hba, phy_no)) {1517		dev_warn(dev, "phy%d, wait tx fifo need send break\n",1518			phy_no);1519		txid_auto = hisi_sas_phy_read32(hisi_hba, phy_no,1520					TXID_AUTO);1521		txid_auto |= TXID_AUTO_CTB_MSK;1522		hisi_sas_phy_write32(hisi_hba, phy_no, TXID_AUTO,1523					txid_auto);1524	}1525 1526do_disable:1527	cfg = hisi_sas_phy_read32(hisi_hba, phy_no, PHY_CFG);1528	cfg &= ~PHY_CFG_ENA_MSK;1529	hisi_sas_phy_write32(hisi_hba, phy_no, PHY_CFG, cfg);1530 1531	/* Open axi bus. */1532	axi_val &= ~0x1;1533	hisi_sas_write32(hisi_hba, AXI_MASTER_CFG_BASE +1534		AM_CTRL_GLOBAL, axi_val);1535}1536 1537static void start_phy_v2_hw(struct hisi_hba *hisi_hba, int phy_no)1538{1539	config_id_frame_v2_hw(hisi_hba, phy_no);1540	config_phy_opt_mode_v2_hw(hisi_hba, phy_no);1541	enable_phy_v2_hw(hisi_hba, phy_no);1542}1543 1544static void phy_hard_reset_v2_hw(struct hisi_hba *hisi_hba, int phy_no)1545{1546	struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];1547	u32 txid_auto;1548 1549	hisi_sas_phy_enable(hisi_hba, phy_no, 0);1550	if (phy->identify.device_type == SAS_END_DEVICE) {1551		txid_auto = hisi_sas_phy_read32(hisi_hba, phy_no, TXID_AUTO);1552		hisi_sas_phy_write32(hisi_hba, phy_no, TXID_AUTO,1553					txid_auto | TX_HARDRST_MSK);1554	}1555	msleep(100);1556	hisi_sas_phy_enable(hisi_hba, phy_no, 1);1557}1558 1559static void phy_get_events_v2_hw(struct hisi_hba *hisi_hba, int phy_no)1560{1561	struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];1562	struct asd_sas_phy *sas_phy = &phy->sas_phy;1563	struct sas_phy *sphy = sas_phy->phy;1564	u32 err4_reg_val, err6_reg_val;1565 1566	/* loss dword syn, phy reset problem */1567	err4_reg_val = hisi_sas_phy_read32(hisi_hba, phy_no, SAS_ERR_CNT4_REG);1568 1569	/* disparity err, invalid dword */1570	err6_reg_val = hisi_sas_phy_read32(hisi_hba, phy_no, SAS_ERR_CNT6_REG);1571 1572	sphy->loss_of_dword_sync_count += (err4_reg_val >> 16) & 0xFFFF;1573	sphy->phy_reset_problem_count += err4_reg_val & 0xFFFF;1574	sphy->invalid_dword_count += (err6_reg_val & 0xFF0000) >> 16;1575	sphy->running_disparity_error_count += err6_reg_val & 0xFF;1576}1577 1578static void phys_init_v2_hw(struct hisi_hba *hisi_hba)1579{1580	int i;1581 1582	for (i = 0; i < hisi_hba->n_phy; i++) {1583		struct hisi_sas_phy *phy = &hisi_hba->phy[i];1584		struct asd_sas_phy *sas_phy = &phy->sas_phy;1585 1586		if (!sas_phy->phy->enabled)1587			continue;1588 1589		hisi_sas_phy_enable(hisi_hba, i, 1);1590	}1591}1592 1593static void sl_notify_ssp_v2_hw(struct hisi_hba *hisi_hba, int phy_no)1594{1595	u32 sl_control;1596 1597	sl_control = hisi_sas_phy_read32(hisi_hba, phy_no, SL_CONTROL);1598	sl_control |= SL_CONTROL_NOTIFY_EN_MSK;1599	hisi_sas_phy_write32(hisi_hba, phy_no, SL_CONTROL, sl_control);1600	msleep(1);1601	sl_control = hisi_sas_phy_read32(hisi_hba, phy_no, SL_CONTROL);1602	sl_control &= ~SL_CONTROL_NOTIFY_EN_MSK;1603	hisi_sas_phy_write32(hisi_hba, phy_no, SL_CONTROL, sl_control);1604}1605 1606static enum sas_linkrate phy_get_max_linkrate_v2_hw(void)1607{1608	return SAS_LINK_RATE_12_0_GBPS;1609}1610 1611static void phy_set_linkrate_v2_hw(struct hisi_hba *hisi_hba, int phy_no,1612		struct sas_phy_linkrates *r)1613{1614	enum sas_linkrate max = r->maximum_linkrate;1615	u32 prog_phy_link_rate = 0x800;1616 1617	prog_phy_link_rate |= hisi_sas_get_prog_phy_linkrate_mask(max);1618	hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE,1619			     prog_phy_link_rate);1620}1621 1622static int get_wideport_bitmap_v2_hw(struct hisi_hba *hisi_hba, int port_id)1623{1624	int i, bitmap = 0;1625	u32 phy_port_num_ma = hisi_sas_read32(hisi_hba, PHY_PORT_NUM_MA);1626	u32 phy_state = hisi_sas_read32(hisi_hba, PHY_STATE);1627 1628	for (i = 0; i < (hisi_hba->n_phy < 9 ? hisi_hba->n_phy : 8); i++)1629		if (phy_state & 1 << i)1630			if (((phy_port_num_ma >> (i * 4)) & 0xf) == port_id)1631				bitmap |= 1 << i;1632 1633	if (hisi_hba->n_phy == 9) {1634		u32 port_state = hisi_sas_read32(hisi_hba, PORT_STATE);1635 1636		if (phy_state & 1 << 8)1637			if (((port_state & PORT_STATE_PHY8_PORT_NUM_MSK) >>1638			     PORT_STATE_PHY8_PORT_NUM_OFF) == port_id)1639				bitmap |= 1 << 9;1640	}1641 1642	return bitmap;1643}1644 1645/* DQ lock must be taken here */1646static void start_delivery_v2_hw(struct hisi_sas_dq *dq)1647{1648	struct hisi_hba *hisi_hba = dq->hisi_hba;1649	struct hisi_sas_slot *s, *s1, *s2 = NULL;1650	int dlvry_queue = dq->id;1651	int wp;1652 1653	list_for_each_entry_safe(s, s1, &dq->list, delivery) {1654		if (!s->ready)1655			break;1656		s2 = s;1657		list_del(&s->delivery);1658	}1659 1660	if (!s2)1661		return;1662 1663	/*1664	 * Ensure that memories for slots built on other CPUs is observed.1665	 */1666	smp_rmb();1667	wp = (s2->dlvry_queue_slot + 1) % HISI_SAS_QUEUE_SLOTS;1668 1669	hisi_sas_write32(hisi_hba, DLVRY_Q_0_WR_PTR + (dlvry_queue * 0x14), wp);1670}1671 1672static void prep_prd_sge_v2_hw(struct hisi_hba *hisi_hba,1673			      struct hisi_sas_slot *slot,1674			      struct hisi_sas_cmd_hdr *hdr,1675			      struct scatterlist *scatter,1676			      int n_elem)1677{1678	struct hisi_sas_sge_page *sge_page = hisi_sas_sge_addr_mem(slot);1679	struct scatterlist *sg;1680	int i;1681 1682	for_each_sg(scatter, sg, n_elem, i) {1683		struct hisi_sas_sge *entry = &sge_page->sge[i];1684 1685		entry->addr = cpu_to_le64(sg_dma_address(sg));1686		entry->page_ctrl_0 = entry->page_ctrl_1 = 0;1687		entry->data_len = cpu_to_le32(sg_dma_len(sg));1688		entry->data_off = 0;1689	}1690 1691	hdr->prd_table_addr = cpu_to_le64(hisi_sas_sge_addr_dma(slot));1692 1693	hdr->sg_len = cpu_to_le32(n_elem << CMD_HDR_DATA_SGL_LEN_OFF);1694}1695 1696static void prep_smp_v2_hw(struct hisi_hba *hisi_hba,1697			  struct hisi_sas_slot *slot)1698{1699	struct sas_task *task = slot->task;1700	struct hisi_sas_cmd_hdr *hdr = slot->cmd_hdr;1701	struct domain_device *device = task->dev;1702	struct hisi_sas_port *port = slot->port;1703	struct scatterlist *sg_req;1704	struct hisi_sas_device *sas_dev = device->lldd_dev;1705	dma_addr_t req_dma_addr;1706	unsigned int req_len;1707 1708	/* req */1709	sg_req = &task->smp_task.smp_req;1710	req_dma_addr = sg_dma_address(sg_req);1711	req_len = sg_dma_len(&task->smp_task.smp_req);1712 1713	/* create header */1714	/* dw0 */1715	hdr->dw0 = cpu_to_le32((port->id << CMD_HDR_PORT_OFF) |1716			       (1 << CMD_HDR_PRIORITY_OFF) | /* high pri */1717			       (2 << CMD_HDR_CMD_OFF)); /* smp */1718 1719	/* map itct entry */1720	hdr->dw1 = cpu_to_le32((sas_dev->device_id << CMD_HDR_DEV_ID_OFF) |1721			       (1 << CMD_HDR_FRAME_TYPE_OFF) |1722			       (DIR_NO_DATA << CMD_HDR_DIR_OFF));1723 1724	/* dw2 */1725	hdr->dw2 = cpu_to_le32((((req_len - 4) / 4) << CMD_HDR_CFL_OFF) |1726			       (HISI_SAS_MAX_SMP_RESP_SZ / 4 <<1727			       CMD_HDR_MRFL_OFF));1728 1729	hdr->transfer_tags = cpu_to_le32(slot->idx << CMD_HDR_IPTT_OFF);1730 1731	hdr->cmd_table_addr = cpu_to_le64(req_dma_addr);1732	hdr->sts_buffer_addr = cpu_to_le64(hisi_sas_status_buf_addr_dma(slot));1733}1734 1735static void prep_ssp_v2_hw(struct hisi_hba *hisi_hba,1736			  struct hisi_sas_slot *slot)1737{1738	struct sas_task *task = slot->task;1739	struct hisi_sas_cmd_hdr *hdr = slot->cmd_hdr;1740	struct domain_device *device = task->dev;1741	struct hisi_sas_device *sas_dev = device->lldd_dev;1742	struct hisi_sas_port *port = slot->port;1743	struct sas_ssp_task *ssp_task = &task->ssp_task;1744	struct scsi_cmnd *scsi_cmnd = ssp_task->cmd;1745	struct sas_tmf_task *tmf = slot->tmf;1746	int has_data = 0, priority = !!tmf;1747	u8 *buf_cmd;1748	u32 dw1 = 0, dw2 = 0;1749 1750	hdr->dw0 = cpu_to_le32((1 << CMD_HDR_RESP_REPORT_OFF) |1751			       (2 << CMD_HDR_TLR_CTRL_OFF) |1752			       (port->id << CMD_HDR_PORT_OFF) |1753			       (priority << CMD_HDR_PRIORITY_OFF) |1754			       (1 << CMD_HDR_CMD_OFF)); /* ssp */1755 1756	dw1 = 1 << CMD_HDR_VDTL_OFF;1757	if (tmf) {1758		dw1 |= 2 << CMD_HDR_FRAME_TYPE_OFF;1759		dw1 |= DIR_NO_DATA << CMD_HDR_DIR_OFF;1760	} else {1761		dw1 |= 1 << CMD_HDR_FRAME_TYPE_OFF;1762		switch (scsi_cmnd->sc_data_direction) {1763		case DMA_TO_DEVICE:1764			has_data = 1;1765			dw1 |= DIR_TO_DEVICE << CMD_HDR_DIR_OFF;1766			break;1767		case DMA_FROM_DEVICE:1768			has_data = 1;1769			dw1 |= DIR_TO_INI << CMD_HDR_DIR_OFF;1770			break;1771		default:1772			dw1 &= ~CMD_HDR_DIR_MSK;1773		}1774	}1775 1776	/* map itct entry */1777	dw1 |= sas_dev->device_id << CMD_HDR_DEV_ID_OFF;1778	hdr->dw1 = cpu_to_le32(dw1);1779 1780	dw2 = (((sizeof(struct ssp_command_iu) + sizeof(struct ssp_frame_hdr)1781	      + 3) / 4) << CMD_HDR_CFL_OFF) |1782	      ((HISI_SAS_MAX_SSP_RESP_SZ / 4) << CMD_HDR_MRFL_OFF) |1783	      (2 << CMD_HDR_SG_MOD_OFF);1784	hdr->dw2 = cpu_to_le32(dw2);1785 1786	hdr->transfer_tags = cpu_to_le32(slot->idx);1787 1788	if (has_data)1789		prep_prd_sge_v2_hw(hisi_hba, slot, hdr, task->scatter,1790					slot->n_elem);1791 1792	hdr->data_transfer_len = cpu_to_le32(task->total_xfer_len);1793	hdr->cmd_table_addr = cpu_to_le64(hisi_sas_cmd_hdr_addr_dma(slot));1794	hdr->sts_buffer_addr = cpu_to_le64(hisi_sas_status_buf_addr_dma(slot));1795 1796	buf_cmd = hisi_sas_cmd_hdr_addr_mem(slot) +1797		sizeof(struct ssp_frame_hdr);1798 1799	memcpy(buf_cmd, &task->ssp_task.LUN, 8);1800	if (!tmf) {1801		buf_cmd[9] = task->ssp_task.task_attr;1802		memcpy(buf_cmd + 12, task->ssp_task.cmd->cmnd,1803				task->ssp_task.cmd->cmd_len);1804	} else {1805		buf_cmd[10] = tmf->tmf;1806		switch (tmf->tmf) {1807		case TMF_ABORT_TASK:1808		case TMF_QUERY_TASK:1809			buf_cmd[12] =1810				(tmf->tag_of_task_to_be_managed >> 8) & 0xff;1811			buf_cmd[13] =1812				tmf->tag_of_task_to_be_managed & 0xff;1813			break;1814		default:1815			break;1816		}1817	}1818}1819 1820#define TRANS_TX_ERR	01821#define TRANS_RX_ERR	11822#define DMA_TX_ERR		21823#define SIPC_RX_ERR		31824#define DMA_RX_ERR		41825 1826#define DMA_TX_ERR_OFF	01827#define DMA_TX_ERR_MSK	(0xffff << DMA_TX_ERR_OFF)1828#define SIPC_RX_ERR_OFF	161829#define SIPC_RX_ERR_MSK (0xffff << SIPC_RX_ERR_OFF)1830 1831static int parse_trans_tx_err_code_v2_hw(u32 err_msk)1832{1833	static const u8 trans_tx_err_code_prio[] = {1834		TRANS_TX_OPEN_FAIL_WITH_IT_NEXUS_LOSS,1835		TRANS_TX_ERR_PHY_NOT_ENABLE,1836		TRANS_TX_OPEN_CNX_ERR_WRONG_DESTINATION,1837		TRANS_TX_OPEN_CNX_ERR_ZONE_VIOLATION,1838		TRANS_TX_OPEN_CNX_ERR_BY_OTHER,1839		RESERVED0,1840		TRANS_TX_OPEN_CNX_ERR_AIP_TIMEOUT,1841		TRANS_TX_OPEN_CNX_ERR_STP_RESOURCES_BUSY,1842		TRANS_TX_OPEN_CNX_ERR_PROTOCOL_NOT_SUPPORTED,1843		TRANS_TX_OPEN_CNX_ERR_CONNECTION_RATE_NOT_SUPPORTED,1844		TRANS_TX_OPEN_CNX_ERR_BAD_DESTINATION,1845		TRANS_TX_OPEN_CNX_ERR_BREAK_RCVD,1846		TRANS_TX_OPEN_CNX_ERR_LOW_PHY_POWER,1847		TRANS_TX_OPEN_CNX_ERR_PATHWAY_BLOCKED,1848		TRANS_TX_OPEN_CNX_ERR_OPEN_TIMEOUT,1849		TRANS_TX_OPEN_CNX_ERR_NO_DESTINATION,1850		TRANS_TX_OPEN_RETRY_ERR_THRESHOLD_REACHED,1851		TRANS_TX_ERR_WITH_CLOSE_PHYDISALE,1852		TRANS_TX_ERR_WITH_CLOSE_DWS_TIMEOUT,1853		TRANS_TX_ERR_WITH_CLOSE_COMINIT,1854		TRANS_TX_ERR_WITH_BREAK_TIMEOUT,1855		TRANS_TX_ERR_WITH_BREAK_REQUEST,1856		TRANS_TX_ERR_WITH_BREAK_RECEVIED,1857		TRANS_TX_ERR_WITH_CLOSE_TIMEOUT,1858		TRANS_TX_ERR_WITH_CLOSE_NORMAL,1859		TRANS_TX_ERR_WITH_NAK_RECEVIED,1860		TRANS_TX_ERR_WITH_ACK_NAK_TIMEOUT,1861		TRANS_TX_ERR_WITH_CREDIT_TIMEOUT,1862		TRANS_TX_ERR_WITH_IPTT_CONFLICT,1863		TRANS_TX_ERR_WITH_OPEN_BY_DES_OR_OTHERS,1864		TRANS_TX_ERR_WITH_WAIT_RECV_TIMEOUT,1865	};1866	int index, i;1867 1868	for (i = 0; i < ARRAY_SIZE(trans_tx_err_code_prio); i++) {1869		index = trans_tx_err_code_prio[i] - TRANS_TX_FAIL_BASE;1870		if (err_msk & (1 << index))1871			return trans_tx_err_code_prio[i];1872	}1873	return -1;1874}1875 1876static int parse_trans_rx_err_code_v2_hw(u32 err_msk)1877{1878	static const u8 trans_rx_err_code_prio[] = {1879		TRANS_RX_ERR_WITH_RXFRAME_CRC_ERR,1880		TRANS_RX_ERR_WITH_RXFIS_8B10B_DISP_ERR,1881		TRANS_RX_ERR_WITH_RXFRAME_HAVE_ERRPRM,1882		TRANS_RX_ERR_WITH_RXFIS_DECODE_ERROR,1883		TRANS_RX_ERR_WITH_RXFIS_CRC_ERR,1884		TRANS_RX_ERR_WITH_RXFRAME_LENGTH_OVERRUN,1885		TRANS_RX_ERR_WITH_RXFIS_RX_SYNCP,1886		TRANS_RX_ERR_WITH_LINK_BUF_OVERRUN,1887		TRANS_RX_ERR_WITH_CLOSE_PHY_DISABLE,1888		TRANS_RX_ERR_WITH_CLOSE_DWS_TIMEOUT,1889		TRANS_RX_ERR_WITH_CLOSE_COMINIT,1890		TRANS_RX_ERR_WITH_BREAK_TIMEOUT,1891		TRANS_RX_ERR_WITH_BREAK_REQUEST,1892		TRANS_RX_ERR_WITH_BREAK_RECEVIED,1893		RESERVED1,1894		TRANS_RX_ERR_WITH_CLOSE_NORMAL,1895		TRANS_RX_ERR_WITH_DATA_LEN0,1896		TRANS_RX_ERR_WITH_BAD_HASH,1897		TRANS_RX_XRDY_WLEN_ZERO_ERR,1898		TRANS_RX_SSP_FRM_LEN_ERR,1899		RESERVED2,1900		RESERVED3,1901		RESERVED4,1902		RESERVED5,1903		TRANS_RX_ERR_WITH_BAD_FRM_TYPE,1904		TRANS_RX_SMP_FRM_LEN_ERR,1905		TRANS_RX_SMP_RESP_TIMEOUT_ERR,1906		RESERVED6,1907		RESERVED7,1908		RESERVED8,1909		RESERVED9,1910		TRANS_RX_R_ERR,1911	};1912	int index, i;1913 1914	for (i = 0; i < ARRAY_SIZE(trans_rx_err_code_prio); i++) {1915		index = trans_rx_err_code_prio[i] - TRANS_RX_FAIL_BASE;1916		if (err_msk & (1 << index))1917			return trans_rx_err_code_prio[i];1918	}1919	return -1;1920}1921 1922static int parse_dma_tx_err_code_v2_hw(u32 err_msk)1923{1924	static const u8 dma_tx_err_code_prio[] = {1925		DMA_TX_UNEXP_XFER_ERR,1926		DMA_TX_UNEXP_RETRANS_ERR,1927		DMA_TX_XFER_LEN_OVERFLOW,1928		DMA_TX_XFER_OFFSET_ERR,1929		DMA_TX_RAM_ECC_ERR,1930		DMA_TX_DIF_LEN_ALIGN_ERR,1931		DMA_TX_DIF_CRC_ERR,1932		DMA_TX_DIF_APP_ERR,1933		DMA_TX_DIF_RPP_ERR,1934		DMA_TX_DATA_SGL_OVERFLOW,1935		DMA_TX_DIF_SGL_OVERFLOW,1936	};1937	int index, i;1938 1939	for (i = 0; i < ARRAY_SIZE(dma_tx_err_code_prio); i++) {1940		index = dma_tx_err_code_prio[i] - DMA_TX_ERR_BASE;1941		err_msk = err_msk & DMA_TX_ERR_MSK;1942		if (err_msk & (1 << index))1943			return dma_tx_err_code_prio[i];1944	}1945	return -1;1946}1947 1948static int parse_sipc_rx_err_code_v2_hw(u32 err_msk)1949{1950	static const u8 sipc_rx_err_code_prio[] = {1951		SIPC_RX_FIS_STATUS_ERR_BIT_VLD,1952		SIPC_RX_PIO_WRSETUP_STATUS_DRQ_ERR,1953		SIPC_RX_FIS_STATUS_BSY_BIT_ERR,1954		SIPC_RX_WRSETUP_LEN_ODD_ERR,1955		SIPC_RX_WRSETUP_LEN_ZERO_ERR,1956		SIPC_RX_WRDATA_LEN_NOT_MATCH_ERR,1957		SIPC_RX_NCQ_WRSETUP_OFFSET_ERR,1958		SIPC_RX_NCQ_WRSETUP_AUTO_ACTIVE_ERR,1959		SIPC_RX_SATA_UNEXP_FIS_ERR,1960		SIPC_RX_WRSETUP_ESTATUS_ERR,1961		SIPC_RX_DATA_UNDERFLOW_ERR,1962	};1963	int index, i;1964 1965	for (i = 0; i < ARRAY_SIZE(sipc_rx_err_code_prio); i++) {1966		index = sipc_rx_err_code_prio[i] - SIPC_RX_ERR_BASE;1967		err_msk = err_msk & SIPC_RX_ERR_MSK;1968		if (err_msk & (1 << (index + 0x10)))1969			return sipc_rx_err_code_prio[i];1970	}1971	return -1;1972}1973 1974static int parse_dma_rx_err_code_v2_hw(u32 err_msk)1975{1976	static const u8 dma_rx_err_code_prio[] = {1977		DMA_RX_UNKNOWN_FRM_ERR,1978		DMA_RX_DATA_LEN_OVERFLOW,1979		DMA_RX_DATA_LEN_UNDERFLOW,1980		DMA_RX_DATA_OFFSET_ERR,1981		RESERVED10,1982		DMA_RX_SATA_FRAME_TYPE_ERR,1983		DMA_RX_RESP_BUF_OVERFLOW,1984		DMA_RX_UNEXP_RETRANS_RESP_ERR,1985		DMA_RX_UNEXP_NORM_RESP_ERR,1986		DMA_RX_UNEXP_RDFRAME_ERR,1987		DMA_RX_PIO_DATA_LEN_ERR,1988		DMA_RX_RDSETUP_STATUS_ERR,1989		DMA_RX_RDSETUP_STATUS_DRQ_ERR,1990		DMA_RX_RDSETUP_STATUS_BSY_ERR,1991		DMA_RX_RDSETUP_LEN_ODD_ERR,1992		DMA_RX_RDSETUP_LEN_ZERO_ERR,1993		DMA_RX_RDSETUP_LEN_OVER_ERR,1994		DMA_RX_RDSETUP_OFFSET_ERR,1995		DMA_RX_RDSETUP_ACTIVE_ERR,1996		DMA_RX_RDSETUP_ESTATUS_ERR,1997		DMA_RX_RAM_ECC_ERR,1998		DMA_RX_DIF_CRC_ERR,1999		DMA_RX_DIF_APP_ERR,2000		DMA_RX_DIF_RPP_ERR,2001		DMA_RX_DATA_SGL_OVERFLOW,2002		DMA_RX_DIF_SGL_OVERFLOW,2003	};2004	int index, i;2005 2006	for (i = 0; i < ARRAY_SIZE(dma_rx_err_code_prio); i++) {2007		index = dma_rx_err_code_prio[i] - DMA_RX_ERR_BASE;2008		if (err_msk & (1 << index))2009			return dma_rx_err_code_prio[i];2010	}2011	return -1;2012}2013 2014/* by default, task resp is complete */2015static void slot_err_v2_hw(struct hisi_hba *hisi_hba,2016			   struct sas_task *task,2017			   struct hisi_sas_slot *slot,2018			   int err_phase)2019{2020	struct task_status_struct *ts = &task->task_status;2021	struct hisi_sas_err_record_v2 *err_record =2022			hisi_sas_status_buf_addr_mem(slot);2023	u32 trans_tx_fail_type = le32_to_cpu(err_record->trans_tx_fail_type);2024	u32 trans_rx_fail_type = le32_to_cpu(err_record->trans_rx_fail_type);2025	u16 dma_tx_err_type = le16_to_cpu(err_record->dma_tx_err_type);2026	u16 sipc_rx_err_type = le16_to_cpu(err_record->sipc_rx_err_type);2027	u32 dma_rx_err_type = le32_to_cpu(err_record->dma_rx_err_type);2028	struct hisi_sas_complete_v2_hdr *complete_queue =2029			hisi_hba->complete_hdr[slot->cmplt_queue];2030	struct hisi_sas_complete_v2_hdr *complete_hdr =2031			&complete_queue[slot->cmplt_queue_slot];2032	u32 dw0 = le32_to_cpu(complete_hdr->dw0);2033	int error = -1;2034 2035	if (err_phase == 1) {2036		/* error in TX phase, the priority of error is: DW2 > DW0 */2037		error = parse_dma_tx_err_code_v2_hw(dma_tx_err_type);2038		if (error == -1)2039			error = parse_trans_tx_err_code_v2_hw(2040					trans_tx_fail_type);2041	} else if (err_phase == 2) {2042		/* error in RX phase, the priority is: DW1 > DW3 > DW2 */2043		error = parse_trans_rx_err_code_v2_hw(trans_rx_fail_type);2044		if (error == -1) {2045			error = parse_dma_rx_err_code_v2_hw(2046					dma_rx_err_type);2047			if (error == -1)2048				error = parse_sipc_rx_err_code_v2_hw(2049						sipc_rx_err_type);2050		}2051	}2052 2053	switch (task->task_proto) {2054	case SAS_PROTOCOL_SSP:2055	{2056		switch (error) {2057		case TRANS_TX_OPEN_CNX_ERR_NO_DESTINATION:2058		{2059			ts->stat = SAS_OPEN_REJECT;2060			ts->open_rej_reason = SAS_OREJ_NO_DEST;2061			break;2062		}2063		case TRANS_TX_OPEN_CNX_ERR_PROTOCOL_NOT_SUPPORTED:2064		{2065			ts->stat = SAS_OPEN_REJECT;2066			ts->open_rej_reason = SAS_OREJ_EPROTO;2067			break;2068		}2069		case TRANS_TX_OPEN_CNX_ERR_CONNECTION_RATE_NOT_SUPPORTED:2070		{2071			ts->stat = SAS_OPEN_REJECT;2072			ts->open_rej_reason = SAS_OREJ_CONN_RATE;2073			break;2074		}2075		case TRANS_TX_OPEN_CNX_ERR_BAD_DESTINATION:2076		{2077			ts->stat = SAS_OPEN_REJECT;2078			ts->open_rej_reason = SAS_OREJ_BAD_DEST;2079			break;2080		}2081		case TRANS_TX_OPEN_CNX_ERR_WRONG_DESTINATION:2082		{2083			ts->stat = SAS_OPEN_REJECT;2084			ts->open_rej_reason = SAS_OREJ_WRONG_DEST;2085			break;2086		}2087		case DMA_RX_UNEXP_NORM_RESP_ERR:2088		case TRANS_TX_OPEN_CNX_ERR_ZONE_VIOLATION:2089		case DMA_RX_RESP_BUF_OVERFLOW:2090		{2091			ts->stat = SAS_OPEN_REJECT;2092			ts->open_rej_reason = SAS_OREJ_UNKNOWN;2093			break;2094		}2095		case TRANS_TX_OPEN_CNX_ERR_LOW_PHY_POWER:2096		{2097			/* not sure */2098			ts->stat = SAS_DEV_NO_RESPONSE;2099			break;2100		}2101		case DMA_RX_DATA_LEN_OVERFLOW:2102		{2103			ts->stat = SAS_DATA_OVERRUN;2104			ts->residual = 0;2105			break;2106		}2107		case DMA_RX_DATA_LEN_UNDERFLOW:2108		{2109			ts->residual = trans_tx_fail_type;2110			ts->stat = SAS_DATA_UNDERRUN;2111			break;2112		}2113		case TRANS_TX_OPEN_FAIL_WITH_IT_NEXUS_LOSS:2114		case TRANS_TX_ERR_PHY_NOT_ENABLE:2115		case TRANS_TX_OPEN_CNX_ERR_BY_OTHER:2116		case TRANS_TX_OPEN_CNX_ERR_AIP_TIMEOUT:2117		case TRANS_TX_OPEN_CNX_ERR_BREAK_RCVD:2118		case TRANS_TX_OPEN_CNX_ERR_PATHWAY_BLOCKED:2119		case TRANS_TX_OPEN_CNX_ERR_OPEN_TIMEOUT:2120		case TRANS_TX_OPEN_RETRY_ERR_THRESHOLD_REACHED:2121		case TRANS_TX_ERR_WITH_BREAK_TIMEOUT:2122		case TRANS_TX_ERR_WITH_BREAK_REQUEST:2123		case TRANS_TX_ERR_WITH_BREAK_RECEVIED:2124		case TRANS_TX_ERR_WITH_CLOSE_TIMEOUT:2125		case TRANS_TX_ERR_WITH_CLOSE_NORMAL:2126		case TRANS_TX_ERR_WITH_CLOSE_PHYDISALE:2127		case TRANS_TX_ERR_WITH_CLOSE_DWS_TIMEOUT:2128		case TRANS_TX_ERR_WITH_CLOSE_COMINIT:2129		case TRANS_TX_ERR_WITH_NAK_RECEVIED:2130		case TRANS_TX_ERR_WITH_ACK_NAK_TIMEOUT:2131		case TRANS_TX_ERR_WITH_CREDIT_TIMEOUT:2132		case TRANS_TX_ERR_WITH_IPTT_CONFLICT:2133		case TRANS_RX_ERR_WITH_RXFRAME_CRC_ERR:2134		case TRANS_RX_ERR_WITH_RXFIS_8B10B_DISP_ERR:2135		case TRANS_RX_ERR_WITH_RXFRAME_HAVE_ERRPRM:2136		case TRANS_RX_ERR_WITH_LINK_BUF_OVERRUN:2137		case TRANS_RX_ERR_WITH_BREAK_TIMEOUT:2138		case TRANS_RX_ERR_WITH_BREAK_REQUEST:2139		case TRANS_RX_ERR_WITH_BREAK_RECEVIED:2140		case TRANS_RX_ERR_WITH_CLOSE_NORMAL:2141		case TRANS_RX_ERR_WITH_CLOSE_DWS_TIMEOUT:2142		case TRANS_RX_ERR_WITH_CLOSE_COMINIT:2143		case TRANS_TX_ERR_FRAME_TXED:2144		case TRANS_RX_ERR_WITH_CLOSE_PHY_DISABLE:2145		case TRANS_RX_ERR_WITH_DATA_LEN0:2146		case TRANS_RX_ERR_WITH_BAD_HASH:2147		case TRANS_RX_XRDY_WLEN_ZERO_ERR:2148		case TRANS_RX_SSP_FRM_LEN_ERR:2149		case TRANS_RX_ERR_WITH_BAD_FRM_TYPE:2150		case DMA_TX_DATA_SGL_OVERFLOW:2151		case DMA_TX_UNEXP_XFER_ERR:2152		case DMA_TX_UNEXP_RETRANS_ERR:2153		case DMA_TX_XFER_LEN_OVERFLOW:2154		case DMA_TX_XFER_OFFSET_ERR:2155		case SIPC_RX_DATA_UNDERFLOW_ERR:2156		case DMA_RX_DATA_SGL_OVERFLOW:2157		case DMA_RX_DATA_OFFSET_ERR:2158		case DMA_RX_RDSETUP_LEN_ODD_ERR:2159		case DMA_RX_RDSETUP_LEN_ZERO_ERR:2160		case DMA_RX_RDSETUP_LEN_OVER_ERR:2161		case DMA_RX_SATA_FRAME_TYPE_ERR:2162		case DMA_RX_UNKNOWN_FRM_ERR:2163		{2164			/* This will request a retry */2165			ts->stat = SAS_QUEUE_FULL;2166			slot->abort = 1;2167			break;2168		}2169		default:2170			break;2171		}2172	}2173		break;2174	case SAS_PROTOCOL_SMP:2175		ts->stat = SAS_SAM_STAT_CHECK_CONDITION;2176		break;2177 2178	case SAS_PROTOCOL_SATA:2179	case SAS_PROTOCOL_STP:2180	case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:2181	{2182		switch (error) {2183		case TRANS_TX_OPEN_CNX_ERR_NO_DESTINATION:2184		{2185			ts->stat = SAS_OPEN_REJECT;2186			ts->open_rej_reason = SAS_OREJ_NO_DEST;2187			break;2188		}2189		case TRANS_TX_OPEN_CNX_ERR_LOW_PHY_POWER:2190		{2191			ts->resp = SAS_TASK_UNDELIVERED;2192			ts->stat = SAS_DEV_NO_RESPONSE;2193			break;2194		}2195		case TRANS_TX_OPEN_CNX_ERR_PROTOCOL_NOT_SUPPORTED:2196		{2197			ts->stat = SAS_OPEN_REJECT;2198			ts->open_rej_reason = SAS_OREJ_EPROTO;2199			break;2200		}2201		case TRANS_TX_OPEN_CNX_ERR_CONNECTION_RATE_NOT_SUPPORTED:2202		{2203			ts->stat = SAS_OPEN_REJECT;2204			ts->open_rej_reason = SAS_OREJ_CONN_RATE;2205			break;2206		}2207		case TRANS_TX_OPEN_CNX_ERR_BAD_DESTINATION:2208		{2209			ts->stat = SAS_OPEN_REJECT;2210			ts->open_rej_reason = SAS_OREJ_CONN_RATE;2211			break;2212		}2213		case TRANS_TX_OPEN_CNX_ERR_WRONG_DESTINATION:2214		{2215			ts->stat = SAS_OPEN_REJECT;2216			ts->open_rej_reason = SAS_OREJ_WRONG_DEST;2217			break;2218		}2219		case DMA_RX_RESP_BUF_OVERFLOW:2220		case DMA_RX_UNEXP_NORM_RESP_ERR:2221		case TRANS_TX_OPEN_CNX_ERR_ZONE_VIOLATION:2222		{2223			ts->stat = SAS_OPEN_REJECT;2224			ts->open_rej_reason = SAS_OREJ_UNKNOWN;2225			break;2226		}2227		case DMA_RX_DATA_LEN_OVERFLOW:2228		{2229			ts->stat = SAS_DATA_OVERRUN;2230			ts->residual = 0;2231			break;2232		}2233		case DMA_RX_DATA_LEN_UNDERFLOW:2234		{2235			ts->residual = trans_tx_fail_type;2236			ts->stat = SAS_DATA_UNDERRUN;2237			break;2238		}2239		case TRANS_TX_OPEN_FAIL_WITH_IT_NEXUS_LOSS:2240		case TRANS_TX_ERR_PHY_NOT_ENABLE:2241		case TRANS_TX_OPEN_CNX_ERR_BY_OTHER:2242		case TRANS_TX_OPEN_CNX_ERR_AIP_TIMEOUT:2243		case TRANS_TX_OPEN_CNX_ERR_BREAK_RCVD:2244		case TRANS_TX_OPEN_CNX_ERR_PATHWAY_BLOCKED:2245		case TRANS_TX_OPEN_CNX_ERR_OPEN_TIMEOUT:2246		case TRANS_TX_OPEN_RETRY_ERR_THRESHOLD_REACHED:2247		case TRANS_TX_ERR_WITH_BREAK_TIMEOUT:2248		case TRANS_TX_ERR_WITH_BREAK_REQUEST:2249		case TRANS_TX_ERR_WITH_BREAK_RECEVIED:2250		case TRANS_TX_ERR_WITH_CLOSE_TIMEOUT:2251		case TRANS_TX_ERR_WITH_CLOSE_NORMAL:2252		case TRANS_TX_ERR_WITH_CLOSE_PHYDISALE:2253		case TRANS_TX_ERR_WITH_CLOSE_DWS_TIMEOUT:2254		case TRANS_TX_ERR_WITH_CLOSE_COMINIT:2255		case TRANS_TX_ERR_WITH_ACK_NAK_TIMEOUT:2256		case TRANS_TX_ERR_WITH_CREDIT_TIMEOUT:2257		case TRANS_TX_ERR_WITH_OPEN_BY_DES_OR_OTHERS:2258		case TRANS_TX_ERR_WITH_WAIT_RECV_TIMEOUT:2259		case TRANS_RX_ERR_WITH_RXFRAME_HAVE_ERRPRM:2260		case TRANS_RX_ERR_WITH_RXFIS_8B10B_DISP_ERR:2261		case TRANS_RX_ERR_WITH_RXFIS_DECODE_ERROR:2262		case TRANS_RX_ERR_WITH_RXFIS_CRC_ERR:2263		case TRANS_RX_ERR_WITH_RXFRAME_LENGTH_OVERRUN:2264		case TRANS_RX_ERR_WITH_RXFIS_RX_SYNCP:2265		case TRANS_RX_ERR_WITH_LINK_BUF_OVERRUN:2266		case TRANS_RX_ERR_WITH_BREAK_TIMEOUT:2267		case TRANS_RX_ERR_WITH_BREAK_REQUEST:2268		case TRANS_RX_ERR_WITH_BREAK_RECEVIED:2269		case TRANS_RX_ERR_WITH_CLOSE_NORMAL:2270		case TRANS_RX_ERR_WITH_CLOSE_PHY_DISABLE:2271		case TRANS_RX_ERR_WITH_CLOSE_DWS_TIMEOUT:2272		case TRANS_RX_ERR_WITH_CLOSE_COMINIT:2273		case TRANS_RX_ERR_WITH_DATA_LEN0:2274		case TRANS_RX_ERR_WITH_BAD_HASH:2275		case TRANS_RX_XRDY_WLEN_ZERO_ERR:2276		case TRANS_RX_ERR_WITH_BAD_FRM_TYPE:2277		case DMA_TX_DATA_SGL_OVERFLOW:2278		case DMA_TX_UNEXP_XFER_ERR:2279		case DMA_TX_UNEXP_RETRANS_ERR:2280		case DMA_TX_XFER_LEN_OVERFLOW:2281		case DMA_TX_XFER_OFFSET_ERR:2282		case SIPC_RX_FIS_STATUS_ERR_BIT_VLD:2283		case SIPC_RX_PIO_WRSETUP_STATUS_DRQ_ERR:2284		case SIPC_RX_FIS_STATUS_BSY_BIT_ERR:2285		case SIPC_RX_WRSETUP_LEN_ODD_ERR:2286		case SIPC_RX_WRSETUP_LEN_ZERO_ERR:2287		case SIPC_RX_WRDATA_LEN_NOT_MATCH_ERR:2288		case SIPC_RX_SATA_UNEXP_FIS_ERR:2289		case DMA_RX_DATA_SGL_OVERFLOW:2290		case DMA_RX_DATA_OFFSET_ERR:2291		case DMA_RX_SATA_FRAME_TYPE_ERR:2292		case DMA_RX_UNEXP_RDFRAME_ERR:2293		case DMA_RX_PIO_DATA_LEN_ERR:2294		case DMA_RX_RDSETUP_STATUS_ERR:2295		case DMA_RX_RDSETUP_STATUS_DRQ_ERR:2296		case DMA_RX_RDSETUP_STATUS_BSY_ERR:2297		case DMA_RX_RDSETUP_LEN_ODD_ERR:2298		case DMA_RX_RDSETUP_LEN_ZERO_ERR:2299		case DMA_RX_RDSETUP_LEN_OVER_ERR:2300		case DMA_RX_RDSETUP_OFFSET_ERR:2301		case DMA_RX_RDSETUP_ACTIVE_ERR:2302		case DMA_RX_RDSETUP_ESTATUS_ERR:2303		case DMA_RX_UNKNOWN_FRM_ERR:2304		case TRANS_RX_SSP_FRM_LEN_ERR:2305		case TRANS_TX_OPEN_CNX_ERR_STP_RESOURCES_BUSY:2306		{2307			slot->abort = 1;2308			ts->stat = SAS_PHY_DOWN;2309			break;2310		}2311		default:2312		{2313			ts->stat = SAS_PROTO_RESPONSE;2314			break;2315		}2316		}2317		if (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK)2318			hisi_sas_sata_done(task, slot);2319	}2320		break;2321	default:2322		break;2323	}2324}2325 2326static void slot_complete_v2_hw(struct hisi_hba *hisi_hba,2327				struct hisi_sas_slot *slot)2328{2329	struct sas_task *task = slot->task;2330	struct hisi_sas_device *sas_dev;2331	struct device *dev = hisi_hba->dev;2332	struct task_status_struct *ts;2333	struct domain_device *device;2334	struct sas_ha_struct *ha;2335	struct hisi_sas_complete_v2_hdr *complete_queue =2336			hisi_hba->complete_hdr[slot->cmplt_queue];2337	struct hisi_sas_complete_v2_hdr *complete_hdr =2338			&complete_queue[slot->cmplt_queue_slot];2339	unsigned long flags;2340	bool is_internal = slot->is_internal;2341	u32 dw0;2342 2343	if (unlikely(!task || !task->lldd_task || !task->dev))2344		return;2345 2346	ts = &task->task_status;2347	device = task->dev;2348	ha = device->port->ha;2349	sas_dev = device->lldd_dev;2350 2351	spin_lock_irqsave(&task->task_state_lock, flags);2352	task->task_state_flags &= ~SAS_TASK_STATE_PENDING;2353	spin_unlock_irqrestore(&task->task_state_lock, flags);2354 2355	memset(ts, 0, sizeof(*ts));2356	ts->resp = SAS_TASK_COMPLETE;2357 2358	if (unlikely(!sas_dev)) {2359		dev_dbg(dev, "slot complete: port has no device\n");2360		ts->stat = SAS_PHY_DOWN;2361		goto out;2362	}2363 2364	/* Use SAS+TMF status codes */2365	dw0 = le32_to_cpu(complete_hdr->dw0);2366	switch ((dw0 & CMPLT_HDR_ABORT_STAT_MSK) >>2367		CMPLT_HDR_ABORT_STAT_OFF) {2368	case STAT_IO_ABORTED:2369		/* this io has been aborted by abort command */2370		ts->stat = SAS_ABORTED_TASK;2371		goto out;2372	case STAT_IO_COMPLETE:2373		/* internal abort command complete */2374		ts->stat = TMF_RESP_FUNC_SUCC;2375		del_timer_sync(&slot->internal_abort_timer);2376		goto out;2377	case STAT_IO_NO_DEVICE:2378		ts->stat = TMF_RESP_FUNC_COMPLETE;2379		del_timer_sync(&slot->internal_abort_timer);2380		goto out;2381	case STAT_IO_NOT_VALID:2382		/* abort single io, controller don't find2383		 * the io need to abort2384		 */2385		ts->stat = TMF_RESP_FUNC_FAILED;2386		del_timer_sync(&slot->internal_abort_timer);2387		goto out;2388	default:2389		break;2390	}2391 2392	if ((dw0 & CMPLT_HDR_ERX_MSK) && (!(dw0 & CMPLT_HDR_RSPNS_XFRD_MSK))) {2393		u32 err_phase = (dw0 & CMPLT_HDR_ERR_PHASE_MSK)2394				>> CMPLT_HDR_ERR_PHASE_OFF;2395		u32 *error_info = hisi_sas_status_buf_addr_mem(slot);2396 2397		/* Analyse error happens on which phase TX or RX */2398		if (ERR_ON_TX_PHASE(err_phase))2399			slot_err_v2_hw(hisi_hba, task, slot, 1);2400		else if (ERR_ON_RX_PHASE(err_phase))2401			slot_err_v2_hw(hisi_hba, task, slot, 2);2402 2403		if (ts->stat != SAS_DATA_UNDERRUN)2404			dev_info(dev, "erroneous completion iptt=%d task=%pK dev id=%d CQ hdr: 0x%x 0x%x 0x%x 0x%x Error info: 0x%x 0x%x 0x%x 0x%x\n",2405				 slot->idx, task, sas_dev->device_id,2406				 complete_hdr->dw0, complete_hdr->dw1,2407				 complete_hdr->act, complete_hdr->dw3,2408				 error_info[0], error_info[1],2409				 error_info[2], error_info[3]);2410 2411		if (unlikely(slot->abort)) {2412			if (dev_is_sata(device) && task->ata_task.use_ncq)2413				sas_ata_device_link_abort(device, true);2414			else2415				sas_task_abort(task);2416 2417			return;2418		}2419		goto out;2420	}2421 2422	switch (task->task_proto) {2423	case SAS_PROTOCOL_SSP:2424	{2425		struct hisi_sas_status_buffer *status_buffer =2426				hisi_sas_status_buf_addr_mem(slot);2427		struct ssp_response_iu *iu = (struct ssp_response_iu *)2428				&status_buffer->iu[0];2429 2430		sas_ssp_task_response(dev, task, iu);2431		break;2432	}2433	case SAS_PROTOCOL_SMP:2434	{2435		struct scatterlist *sg_resp = &task->smp_task.smp_resp;2436		void *to = page_address(sg_page(sg_resp));2437 2438		ts->stat = SAS_SAM_STAT_GOOD;2439 2440		memcpy(to + sg_resp->offset,2441		       hisi_sas_status_buf_addr_mem(slot) +2442		       sizeof(struct hisi_sas_err_record),2443		       sg_resp->length);2444		break;2445	}2446	case SAS_PROTOCOL_SATA:2447	case SAS_PROTOCOL_STP:2448	case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:2449	{2450		ts->stat = SAS_SAM_STAT_GOOD;2451		if (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK)2452			hisi_sas_sata_done(task, slot);2453		break;2454	}2455	default:2456		ts->stat = SAS_SAM_STAT_CHECK_CONDITION;2457		break;2458	}2459 2460	if (!slot->port->port_attached) {2461		dev_warn(dev, "slot complete: port %d has removed\n",2462			slot->port->sas_port.id);2463		ts->stat = SAS_PHY_DOWN;2464	}2465 2466out:2467	spin_lock_irqsave(&task->task_state_lock, flags);2468	if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {2469		spin_unlock_irqrestore(&task->task_state_lock, flags);2470		dev_info(dev, "slot complete: task(%pK) aborted\n", task);2471		return;2472	}2473	task->task_state_flags |= SAS_TASK_STATE_DONE;2474	spin_unlock_irqrestore(&task->task_state_lock, flags);2475	hisi_sas_slot_task_free(hisi_hba, task, slot, true);2476 2477	if (!is_internal && (task->task_proto != SAS_PROTOCOL_SMP)) {2478		spin_lock_irqsave(&device->done_lock, flags);2479		if (test_bit(SAS_HA_FROZEN, &ha->state)) {2480			spin_unlock_irqrestore(&device->done_lock, flags);2481			dev_info(dev, "slot complete: task(%pK) ignored\n",2482				 task);2483			return;2484		}2485		spin_unlock_irqrestore(&device->done_lock, flags);2486	}2487 2488	if (task->task_done)2489		task->task_done(task);2490}2491 2492static void prep_ata_v2_hw(struct hisi_hba *hisi_hba,2493			  struct hisi_sas_slot *slot)2494{2495	struct sas_task *task = slot->task;2496	struct domain_device *device = task->dev;2497	struct domain_device *parent_dev = device->parent;2498	struct hisi_sas_device *sas_dev = device->lldd_dev;2499	struct hisi_sas_cmd_hdr *hdr = slot->cmd_hdr;2500	struct asd_sas_port *sas_port = device->port;2501	struct hisi_sas_port *port = to_hisi_sas_port(sas_port);2502	struct sas_ata_task *ata_task = &task->ata_task;2503	struct sas_tmf_task *tmf = slot->tmf;2504	u8 *buf_cmd;2505	int has_data = 0, hdr_tag = 0;2506	u32 dw0, dw1 = 0, dw2 = 0;2507 2508	/* create header */2509	/* dw0 */2510	dw0 = port->id << CMD_HDR_PORT_OFF;2511	if (parent_dev && dev_is_expander(parent_dev->dev_type))2512		dw0 |= 3 << CMD_HDR_CMD_OFF;2513	else2514		dw0 |= 4 << CMD_HDR_CMD_OFF;2515 2516	if (tmf && ata_task->force_phy) {2517		dw0 |= CMD_HDR_FORCE_PHY_MSK;2518		dw0 |= (1 << ata_task->force_phy_id) << CMD_HDR_PHY_ID_OFF;2519	}2520 2521	hdr->dw0 = cpu_to_le32(dw0);2522 2523	/* dw1 */2524	switch (task->data_dir) {2525	case DMA_TO_DEVICE:2526		has_data = 1;2527		dw1 |= DIR_TO_DEVICE << CMD_HDR_DIR_OFF;2528		break;2529	case DMA_FROM_DEVICE:2530		has_data = 1;2531		dw1 |= DIR_TO_INI << CMD_HDR_DIR_OFF;2532		break;2533	default:2534		dw1 &= ~CMD_HDR_DIR_MSK;2535	}2536 2537	if ((task->ata_task.fis.command == ATA_CMD_DEV_RESET) &&2538			(task->ata_task.fis.control & ATA_SRST))2539		dw1 |= 1 << CMD_HDR_RESET_OFF;2540 2541	dw1 |= (hisi_sas_get_ata_protocol(2542		&task->ata_task.fis, task->data_dir))2543		<< CMD_HDR_FRAME_TYPE_OFF;2544	dw1 |= sas_dev->device_id << CMD_HDR_DEV_ID_OFF;2545	hdr->dw1 = cpu_to_le32(dw1);2546 2547	/* dw2 */2548	if (task->ata_task.use_ncq) {2549		struct ata_queued_cmd *qc = task->uldd_task;2550 2551		hdr_tag = qc->tag;2552		task->ata_task.fis.sector_count |= (u8) (hdr_tag << 3);2553		dw2 |= hdr_tag << CMD_HDR_NCQ_TAG_OFF;2554	}2555 2556	dw2 |= (HISI_SAS_MAX_STP_RESP_SZ / 4) << CMD_HDR_CFL_OFF |2557			2 << CMD_HDR_SG_MOD_OFF;2558	hdr->dw2 = cpu_to_le32(dw2);2559 2560	/* dw3 */2561	hdr->transfer_tags = cpu_to_le32(slot->idx);2562 2563	if (has_data)2564		prep_prd_sge_v2_hw(hisi_hba, slot, hdr, task->scatter,2565					slot->n_elem);2566 2567	hdr->data_transfer_len = cpu_to_le32(task->total_xfer_len);2568	hdr->cmd_table_addr = cpu_to_le64(hisi_sas_cmd_hdr_addr_dma(slot));2569	hdr->sts_buffer_addr = cpu_to_le64(hisi_sas_status_buf_addr_dma(slot));2570 2571	buf_cmd = hisi_sas_cmd_hdr_addr_mem(slot);2572 2573	if (likely(!task->ata_task.device_control_reg_update))2574		task->ata_task.fis.flags |= 0x80; /* C=1: update ATA cmd reg */2575	/* fill in command FIS */2576	memcpy(buf_cmd, &task->ata_task.fis, sizeof(struct host_to_dev_fis));2577}2578 2579static void hisi_sas_internal_abort_quirk_timeout(struct timer_list *t)2580{2581	struct hisi_sas_slot *slot = from_timer(slot, t, internal_abort_timer);2582	struct hisi_sas_port *port = slot->port;2583	struct asd_sas_port *asd_sas_port;2584	struct asd_sas_phy *sas_phy;2585 2586	if (!port)2587		return;2588 2589	asd_sas_port = &port->sas_port;2590 2591	/* Kick the hardware - send break command */2592	list_for_each_entry(sas_phy, &asd_sas_port->phy_list, port_phy_el) {2593		struct hisi_sas_phy *phy = sas_phy->lldd_phy;2594		struct hisi_hba *hisi_hba = phy->hisi_hba;2595		int phy_no = sas_phy->id;2596		u32 link_dfx2;2597 2598		link_dfx2 = hisi_sas_phy_read32(hisi_hba, phy_no, LINK_DFX2);2599		if ((link_dfx2 == LINK_DFX2_RCVR_HOLD_STS_MSK) ||2600		    (link_dfx2 & LINK_DFX2_SEND_HOLD_STS_MSK)) {2601			u32 txid_auto;2602 2603			txid_auto = hisi_sas_phy_read32(hisi_hba, phy_no,2604							TXID_AUTO);2605			txid_auto |= TXID_AUTO_CTB_MSK;2606			hisi_sas_phy_write32(hisi_hba, phy_no, TXID_AUTO,2607					     txid_auto);2608			return;2609		}2610	}2611}2612 2613static void prep_abort_v2_hw(struct hisi_hba *hisi_hba,2614			     struct hisi_sas_slot *slot)2615{2616	struct sas_task *task = slot->task;2617	struct sas_internal_abort_task *abort = &task->abort_task;2618	struct domain_device *dev = task->dev;2619	struct hisi_sas_cmd_hdr *hdr = slot->cmd_hdr;2620	struct hisi_sas_port *port = slot->port;2621	struct timer_list *timer = &slot->internal_abort_timer;2622	struct hisi_sas_device *sas_dev = dev->lldd_dev;2623 2624	/* setup the quirk timer */2625	timer_setup(timer, hisi_sas_internal_abort_quirk_timeout, 0);2626	/* Set the timeout to 10ms less than internal abort timeout */2627	mod_timer(timer, jiffies + msecs_to_jiffies(100));2628 2629	/* dw0 */2630	hdr->dw0 = cpu_to_le32((5 << CMD_HDR_CMD_OFF) | /*abort*/2631			       (port->id << CMD_HDR_PORT_OFF) |2632			       (dev_is_sata(dev) <<2633				CMD_HDR_ABORT_DEVICE_TYPE_OFF) |2634			       (abort->type << CMD_HDR_ABORT_FLAG_OFF));2635 2636	/* dw1 */2637	hdr->dw1 = cpu_to_le32(sas_dev->device_id << CMD_HDR_DEV_ID_OFF);2638 2639	/* dw7 */2640	hdr->dw7 = cpu_to_le32(abort->tag << CMD_HDR_ABORT_IPTT_OFF);2641	hdr->transfer_tags = cpu_to_le32(slot->idx);2642}2643 2644static int phy_up_v2_hw(int phy_no, struct hisi_hba *hisi_hba)2645{2646	int i, res = IRQ_HANDLED;2647	u32 port_id, link_rate;2648	struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];2649	struct asd_sas_phy *sas_phy = &phy->sas_phy;2650	struct device *dev = hisi_hba->dev;2651	u32 *frame_rcvd = (u32 *)sas_phy->frame_rcvd;2652	struct sas_identify_frame *id = (struct sas_identify_frame *)frame_rcvd;2653 2654	hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 1);2655 2656	if (is_sata_phy_v2_hw(hisi_hba, phy_no))2657		goto end;2658 2659	del_timer(&phy->timer);2660 2661	if (phy_no == 8) {2662		u32 port_state = hisi_sas_read32(hisi_hba, PORT_STATE);2663 2664		port_id = (port_state & PORT_STATE_PHY8_PORT_NUM_MSK) >>2665			  PORT_STATE_PHY8_PORT_NUM_OFF;2666		link_rate = (port_state & PORT_STATE_PHY8_CONN_RATE_MSK) >>2667			    PORT_STATE_PHY8_CONN_RATE_OFF;2668	} else {2669		port_id = hisi_sas_read32(hisi_hba, PHY_PORT_NUM_MA);2670		port_id = (port_id >> (4 * phy_no)) & 0xf;2671		link_rate = hisi_sas_read32(hisi_hba, PHY_CONN_RATE);2672		link_rate = (link_rate >> (phy_no * 4)) & 0xf;2673	}2674 2675	if (port_id == 0xf) {2676		dev_err(dev, "phyup: phy%d invalid portid\n", phy_no);2677		res = IRQ_NONE;2678		goto end;2679	}2680 2681	for (i = 0; i < 6; i++) {2682		u32 idaf = hisi_sas_phy_read32(hisi_hba, phy_no,2683					       RX_IDAF_DWORD0 + (i * 4));2684		frame_rcvd[i] = __swab32(idaf);2685	}2686 2687	sas_phy->linkrate = link_rate;2688	sas_phy->oob_mode = SAS_OOB_MODE;2689	memcpy(sas_phy->attached_sas_addr, &id->sas_addr, SAS_ADDR_SIZE);2690	dev_info(dev, "phyup: phy%d link_rate=%d\n", phy_no, link_rate);2691	phy->port_id = port_id;2692	phy->phy_type &= ~(PORT_TYPE_SAS | PORT_TYPE_SATA);2693	phy->phy_type |= PORT_TYPE_SAS;2694	phy->phy_attached = 1;2695	phy->identify.device_type = id->dev_type;2696	phy->frame_rcvd_size =	sizeof(struct sas_identify_frame);2697	if (phy->identify.device_type == SAS_END_DEVICE)2698		phy->identify.target_port_protocols =2699			SAS_PROTOCOL_SSP;2700	else if (phy->identify.device_type != SAS_PHY_UNUSED) {2701		phy->identify.target_port_protocols =2702			SAS_PROTOCOL_SMP;2703		if (!timer_pending(&hisi_hba->timer))2704			set_link_timer_quirk(hisi_hba);2705	}2706	hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP);2707end:2708	if (phy->reset_completion)2709		complete(phy->reset_completion);2710	hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0,2711			     CHL_INT0_SL_PHY_ENABLE_MSK);2712	hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 0);2713 2714	return res;2715}2716 2717static bool check_any_wideports_v2_hw(struct hisi_hba *hisi_hba)2718{2719	u32 port_state;2720 2721	port_state = hisi_sas_read32(hisi_hba, PORT_STATE);2722	if (port_state & 0x1ff)2723		return true;2724 2725	return false;2726}2727 2728static int phy_down_v2_hw(int phy_no, struct hisi_hba *hisi_hba)2729{2730	u32 phy_state, sl_ctrl, txid_auto;2731	struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];2732	struct hisi_sas_port *port = phy->port;2733	struct device *dev = hisi_hba->dev;2734 2735	del_timer(&phy->timer);2736	hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_NOT_RDY_MSK, 1);2737 2738	phy_state = hisi_sas_read32(hisi_hba, PHY_STATE);2739	dev_info(dev, "phydown: phy%d phy_state=0x%x\n", phy_no, phy_state);2740	hisi_sas_phy_down(hisi_hba, phy_no, (phy_state & 1 << phy_no) ? 1 : 0,2741			  GFP_ATOMIC);2742 2743	sl_ctrl = hisi_sas_phy_read32(hisi_hba, phy_no, SL_CONTROL);2744	hisi_sas_phy_write32(hisi_hba, phy_no, SL_CONTROL,2745			     sl_ctrl & ~SL_CONTROL_CTA_MSK);2746	if (port && !get_wideport_bitmap_v2_hw(hisi_hba, port->id))2747		if (!check_any_wideports_v2_hw(hisi_hba) &&2748				timer_pending(&hisi_hba->timer))2749			del_timer(&hisi_hba->timer);2750 2751	txid_auto = hisi_sas_phy_read32(hisi_hba, phy_no, TXID_AUTO);2752	hisi_sas_phy_write32(hisi_hba, phy_no, TXID_AUTO,2753			     txid_auto | TXID_AUTO_CT3_MSK);2754 2755	hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, CHL_INT0_NOT_RDY_MSK);2756	hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_NOT_RDY_MSK, 0);2757 2758	return IRQ_HANDLED;2759}2760 2761static irqreturn_t int_phy_updown_v2_hw(int irq_no, void *p)2762{2763	struct hisi_hba *hisi_hba = p;2764	u32 irq_msk;2765	int phy_no = 0;2766	irqreturn_t res = IRQ_NONE;2767 2768	irq_msk = (hisi_sas_read32(hisi_hba, HGC_INVLD_DQE_INFO)2769		   >> HGC_INVLD_DQE_INFO_FB_CH0_OFF) & 0x1ff;2770	while (irq_msk) {2771		if (irq_msk  & 1) {2772			u32 reg_value = hisi_sas_phy_read32(hisi_hba, phy_no,2773					    CHL_INT0);2774 2775			switch (reg_value & (CHL_INT0_NOT_RDY_MSK |2776					CHL_INT0_SL_PHY_ENABLE_MSK)) {2777 2778			case CHL_INT0_SL_PHY_ENABLE_MSK:2779				/* phy up */2780				if (phy_up_v2_hw(phy_no, hisi_hba) ==2781				    IRQ_HANDLED)2782					res = IRQ_HANDLED;2783				break;2784 2785			case CHL_INT0_NOT_RDY_MSK:2786				/* phy down */2787				if (phy_down_v2_hw(phy_no, hisi_hba) ==2788				    IRQ_HANDLED)2789					res = IRQ_HANDLED;2790				break;2791 2792			case (CHL_INT0_NOT_RDY_MSK |2793					CHL_INT0_SL_PHY_ENABLE_MSK):2794				reg_value = hisi_sas_read32(hisi_hba,2795						PHY_STATE);2796				if (reg_value & BIT(phy_no)) {2797					/* phy up */2798					if (phy_up_v2_hw(phy_no, hisi_hba) ==2799					    IRQ_HANDLED)2800						res = IRQ_HANDLED;2801				} else {2802					/* phy down */2803					if (phy_down_v2_hw(phy_no, hisi_hba) ==2804					    IRQ_HANDLED)2805						res = IRQ_HANDLED;2806				}2807				break;2808 2809			default:2810				break;2811			}2812 2813		}2814		irq_msk >>= 1;2815		phy_no++;2816	}2817 2818	return res;2819}2820 2821static void phy_bcast_v2_hw(int phy_no, struct hisi_hba *hisi_hba)2822{2823	struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];2824	u32 bcast_status;2825 2826	hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 1);2827	bcast_status = hisi_sas_phy_read32(hisi_hba, phy_no, RX_PRIMS_STATUS);2828	if (bcast_status & RX_BCAST_CHG_MSK)2829		hisi_sas_phy_bcast(phy);2830	hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0,2831			     CHL_INT0_SL_RX_BCST_ACK_MSK);2832	hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 0);2833}2834 2835static const struct hisi_sas_hw_error port_ecc_axi_error[] = {2836	{2837		.irq_msk = BIT(CHL_INT1_DMAC_TX_ECC_ERR_OFF),2838		.msg = "dmac_tx_ecc_bad_err",2839	},2840	{2841		.irq_msk = BIT(CHL_INT1_DMAC_RX_ECC_ERR_OFF),2842		.msg = "dmac_rx_ecc_bad_err",2843	},2844	{2845		.irq_msk = BIT(CHL_INT1_DMAC_TX_AXI_WR_ERR_OFF),2846		.msg = "dma_tx_axi_wr_err",2847	},2848	{2849		.irq_msk = BIT(CHL_INT1_DMAC_TX_AXI_RD_ERR_OFF),2850		.msg = "dma_tx_axi_rd_err",2851	},2852	{2853		.irq_msk = BIT(CHL_INT1_DMAC_RX_AXI_WR_ERR_OFF),2854		.msg = "dma_rx_axi_wr_err",2855	},2856	{2857		.irq_msk = BIT(CHL_INT1_DMAC_RX_AXI_RD_ERR_OFF),2858		.msg = "dma_rx_axi_rd_err",2859	},2860};2861 2862static irqreturn_t int_chnl_int_v2_hw(int irq_no, void *p)2863{2864	struct hisi_hba *hisi_hba = p;2865	struct device *dev = hisi_hba->dev;2866	u32 ent_msk, ent_tmp, irq_msk;2867	int phy_no = 0;2868 2869	ent_msk = hisi_sas_read32(hisi_hba, ENT_INT_SRC_MSK3);2870	ent_tmp = ent_msk;2871	ent_msk |= ENT_INT_SRC_MSK3_ENT95_MSK_MSK;2872	hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, ent_msk);2873 2874	irq_msk = (hisi_sas_read32(hisi_hba, HGC_INVLD_DQE_INFO) >>2875			HGC_INVLD_DQE_INFO_FB_CH3_OFF) & 0x1ff;2876 2877	while (irq_msk) {2878		u32 irq_value0 = hisi_sas_phy_read32(hisi_hba, phy_no,2879						     CHL_INT0);2880		u32 irq_value1 = hisi_sas_phy_read32(hisi_hba, phy_no,2881						     CHL_INT1);2882		u32 irq_value2 = hisi_sas_phy_read32(hisi_hba, phy_no,2883						     CHL_INT2);2884 2885		if ((irq_msk & (1 << phy_no)) && irq_value1) {2886			int i;2887 2888			for (i = 0; i < ARRAY_SIZE(port_ecc_axi_error); i++) {2889				const struct hisi_sas_hw_error *error =2890						&port_ecc_axi_error[i];2891 2892				if (!(irq_value1 & error->irq_msk))2893					continue;2894 2895				dev_warn(dev, "%s error (phy%d 0x%x) found!\n",2896					error->msg, phy_no, irq_value1);2897				queue_work(hisi_hba->wq, &hisi_hba->rst_work);2898			}2899 2900			hisi_sas_phy_write32(hisi_hba, phy_no,2901					     CHL_INT1, irq_value1);2902		}2903 2904		if ((irq_msk & (1 << phy_no)) && irq_value2) {2905			struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];2906 2907			if (irq_value2 & BIT(CHL_INT2_SL_IDAF_TOUT_CONF_OFF)) {2908				dev_warn(dev, "phy%d identify timeout\n",2909					 phy_no);2910				hisi_sas_notify_phy_event(phy,2911						HISI_PHYE_LINK_RESET);2912			}2913 2914			hisi_sas_phy_write32(hisi_hba, phy_no,2915						 CHL_INT2, irq_value2);2916		}2917 2918		if ((irq_msk & (1 << phy_no)) && irq_value0) {2919			if (irq_value0 & CHL_INT0_SL_RX_BCST_ACK_MSK)2920				phy_bcast_v2_hw(phy_no, hisi_hba);2921 2922			if (irq_value0 & CHL_INT0_PHY_RDY_MSK)2923				hisi_sas_phy_oob_ready(hisi_hba, phy_no);2924 2925			hisi_sas_phy_write32(hisi_hba, phy_no,2926					CHL_INT0, irq_value02927					& (~CHL_INT0_HOTPLUG_TOUT_MSK)2928					& (~CHL_INT0_SL_PHY_ENABLE_MSK)2929					& (~CHL_INT0_NOT_RDY_MSK));2930		}2931		irq_msk &= ~(1 << phy_no);2932		phy_no++;2933	}2934 2935	hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, ent_tmp);2936 2937	return IRQ_HANDLED;2938}2939 2940static void2941one_bit_ecc_error_process_v2_hw(struct hisi_hba *hisi_hba, u32 irq_value)2942{2943	struct device *dev = hisi_hba->dev;2944	const struct hisi_sas_hw_error *ecc_error;2945	u32 val;2946	int i;2947 2948	for (i = 0; i < ARRAY_SIZE(one_bit_ecc_errors); i++) {2949		ecc_error = &one_bit_ecc_errors[i];2950		if (irq_value & ecc_error->irq_msk) {2951			val = hisi_sas_read32(hisi_hba, ecc_error->reg);2952			val &= ecc_error->msk;2953			val >>= ecc_error->shift;2954			dev_warn(dev, "%s found: mem addr is 0x%08X\n",2955				 ecc_error->msg, val);2956		}2957	}2958}2959 2960static void multi_bit_ecc_error_process_v2_hw(struct hisi_hba *hisi_hba,2961		u32 irq_value)2962{2963	struct device *dev = hisi_hba->dev;2964	const struct hisi_sas_hw_error *ecc_error;2965	u32 val;2966	int i;2967 2968	for (i = 0; i < ARRAY_SIZE(multi_bit_ecc_errors); i++) {2969		ecc_error = &multi_bit_ecc_errors[i];2970		if (irq_value & ecc_error->irq_msk) {2971			val = hisi_sas_read32(hisi_hba, ecc_error->reg);2972			val &= ecc_error->msk;2973			val >>= ecc_error->shift;2974			dev_err(dev, "%s (0x%x) found: mem addr is 0x%08X\n",2975				ecc_error->msg, irq_value, val);2976			queue_work(hisi_hba->wq, &hisi_hba->rst_work);2977		}2978	}2979 2980	return;2981}2982 2983static irqreturn_t fatal_ecc_int_v2_hw(int irq_no, void *p)2984{2985	struct hisi_hba *hisi_hba = p;2986	u32 irq_value, irq_msk;2987 2988	irq_msk = hisi_sas_read32(hisi_hba, SAS_ECC_INTR_MSK);2989	hisi_sas_write32(hisi_hba, SAS_ECC_INTR_MSK, irq_msk | 0xffffffff);2990 2991	irq_value = hisi_sas_read32(hisi_hba, SAS_ECC_INTR);2992	if (irq_value) {2993		one_bit_ecc_error_process_v2_hw(hisi_hba, irq_value);2994		multi_bit_ecc_error_process_v2_hw(hisi_hba, irq_value);2995	}2996 2997	hisi_sas_write32(hisi_hba, SAS_ECC_INTR, irq_value);2998	hisi_sas_write32(hisi_hba, SAS_ECC_INTR_MSK, irq_msk);2999 3000	return IRQ_HANDLED;3001}3002 3003static const struct hisi_sas_hw_error axi_error[] = {3004	{ .msk = BIT(0), .msg = "IOST_AXI_W_ERR" },3005	{ .msk = BIT(1), .msg = "IOST_AXI_R_ERR" },3006	{ .msk = BIT(2), .msg = "ITCT_AXI_W_ERR" },3007	{ .msk = BIT(3), .msg = "ITCT_AXI_R_ERR" },3008	{ .msk = BIT(4), .msg = "SATA_AXI_W_ERR" },3009	{ .msk = BIT(5), .msg = "SATA_AXI_R_ERR" },3010	{ .msk = BIT(6), .msg = "DQE_AXI_R_ERR" },3011	{ .msk = BIT(7), .msg = "CQE_AXI_W_ERR" },3012	{}3013};3014 3015static const struct hisi_sas_hw_error fifo_error[] = {3016	{ .msk = BIT(8),  .msg = "CQE_WINFO_FIFO" },3017	{ .msk = BIT(9),  .msg = "CQE_MSG_FIFIO" },3018	{ .msk = BIT(10), .msg = "GETDQE_FIFO" },3019	{ .msk = BIT(11), .msg = "CMDP_FIFO" },3020	{ .msk = BIT(12), .msg = "AWTCTRL_FIFO" },3021	{}3022};3023 3024static const struct hisi_sas_hw_error fatal_axi_errors[] = {3025	{3026		.irq_msk = BIT(ENT_INT_SRC3_WP_DEPTH_OFF),3027		.msg = "write pointer and depth",3028	},3029	{3030		.irq_msk = BIT(ENT_INT_SRC3_IPTT_SLOT_NOMATCH_OFF),3031		.msg = "iptt no match slot",3032	},3033	{3034		.irq_msk = BIT(ENT_INT_SRC3_RP_DEPTH_OFF),3035		.msg = "read pointer and depth",3036	},3037	{3038		.irq_msk = BIT(ENT_INT_SRC3_AXI_OFF),3039		.reg = HGC_AXI_FIFO_ERR_INFO,3040		.sub = axi_error,3041	},3042	{3043		.irq_msk = BIT(ENT_INT_SRC3_FIFO_OFF),3044		.reg = HGC_AXI_FIFO_ERR_INFO,3045		.sub = fifo_error,3046	},3047	{3048		.irq_msk = BIT(ENT_INT_SRC3_LM_OFF),3049		.msg = "LM add/fetch list",3050	},3051	{3052		.irq_msk = BIT(ENT_INT_SRC3_ABT_OFF),3053		.msg = "SAS_HGC_ABT fetch LM list",3054	},3055};3056 3057static irqreturn_t fatal_axi_int_v2_hw(int irq_no, void *p)3058{3059	struct hisi_hba *hisi_hba = p;3060	u32 irq_value, irq_msk, err_value;3061	struct device *dev = hisi_hba->dev;3062	const struct hisi_sas_hw_error *axi_error;3063	int i;3064 3065	irq_msk = hisi_sas_read32(hisi_hba, ENT_INT_SRC_MSK3);3066	hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, irq_msk | 0xfffffffe);3067 3068	irq_value = hisi_sas_read32(hisi_hba, ENT_INT_SRC3);3069 3070	for (i = 0; i < ARRAY_SIZE(fatal_axi_errors); i++) {3071		axi_error = &fatal_axi_errors[i];3072		if (!(irq_value & axi_error->irq_msk))3073			continue;3074 3075		hisi_sas_write32(hisi_hba, ENT_INT_SRC3,3076				 1 << axi_error->shift);3077		if (axi_error->sub) {3078			const struct hisi_sas_hw_error *sub = axi_error->sub;3079 3080			err_value = hisi_sas_read32(hisi_hba, axi_error->reg);3081			for (; sub->msk || sub->msg; sub++) {3082				if (!(err_value & sub->msk))3083					continue;3084				dev_err(dev, "%s (0x%x) found!\n",3085					sub->msg, irq_value);3086				queue_work(hisi_hba->wq, &hisi_hba->rst_work);3087			}3088		} else {3089			dev_err(dev, "%s (0x%x) found!\n",3090				axi_error->msg, irq_value);3091			queue_work(hisi_hba->wq, &hisi_hba->rst_work);3092		}3093	}3094 3095	if (irq_value & BIT(ENT_INT_SRC3_ITC_INT_OFF)) {3096		u32 reg_val = hisi_sas_read32(hisi_hba, ITCT_CLR);3097		u32 dev_id = reg_val & ITCT_DEV_MSK;3098		struct hisi_sas_device *sas_dev = &hisi_hba->devices[dev_id];3099 3100		hisi_sas_write32(hisi_hba, ITCT_CLR, 0);3101		dev_dbg(dev, "clear ITCT ok\n");3102		complete(sas_dev->completion);3103	}3104 3105	hisi_sas_write32(hisi_hba, ENT_INT_SRC3, irq_value);3106	hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, irq_msk);3107 3108	return IRQ_HANDLED;3109}3110 3111static irqreturn_t  cq_thread_v2_hw(int irq_no, void *p)3112{3113	struct hisi_sas_cq *cq = p;3114	struct hisi_hba *hisi_hba = cq->hisi_hba;3115	struct hisi_sas_slot *slot;3116	struct hisi_sas_itct *itct;3117	struct hisi_sas_complete_v2_hdr *complete_queue;3118	u32 rd_point = cq->rd_point, wr_point, dev_id;3119	int queue = cq->id;3120 3121	if (unlikely(hisi_hba->reject_stp_links_msk))3122		phys_try_accept_stp_links_v2_hw(hisi_hba);3123 3124	complete_queue = hisi_hba->complete_hdr[queue];3125 3126	wr_point = hisi_sas_read32(hisi_hba, COMPL_Q_0_WR_PTR +3127				   (0x14 * queue));3128 3129	while (rd_point != wr_point) {3130		struct hisi_sas_complete_v2_hdr *complete_hdr;3131		int iptt;3132 3133		complete_hdr = &complete_queue[rd_point];3134 3135		/* Check for NCQ completion */3136		if (complete_hdr->act) {3137			u32 act_tmp = le32_to_cpu(complete_hdr->act);3138			int ncq_tag_count = ffs(act_tmp);3139			u32 dw1 = le32_to_cpu(complete_hdr->dw1);3140 3141			dev_id = (dw1 & CMPLT_HDR_DEV_ID_MSK) >>3142				 CMPLT_HDR_DEV_ID_OFF;3143			itct = &hisi_hba->itct[dev_id];3144 3145			/* The NCQ tags are held in the itct header */3146			while (ncq_tag_count) {3147				__le64 *_ncq_tag = &itct->qw4_15[0], __ncq_tag;3148				u64 ncq_tag;3149 3150				ncq_tag_count--;3151				__ncq_tag = _ncq_tag[ncq_tag_count / 5];3152				ncq_tag = le64_to_cpu(__ncq_tag);3153				iptt = (ncq_tag >> (ncq_tag_count % 5) * 12) &3154				       0xfff;3155 3156				slot = &hisi_hba->slot_info[iptt];3157				slot->cmplt_queue_slot = rd_point;3158				slot->cmplt_queue = queue;3159				slot_complete_v2_hw(hisi_hba, slot);3160 3161				act_tmp &= ~(1 << ncq_tag_count);3162				ncq_tag_count = ffs(act_tmp);3163			}3164		} else {3165			u32 dw1 = le32_to_cpu(complete_hdr->dw1);3166 3167			iptt = dw1 & CMPLT_HDR_IPTT_MSK;3168			slot = &hisi_hba->slot_info[iptt];3169			slot->cmplt_queue_slot = rd_point;3170			slot->cmplt_queue = queue;3171			slot_complete_v2_hw(hisi_hba, slot);3172		}3173 3174		if (++rd_point >= HISI_SAS_QUEUE_SLOTS)3175			rd_point = 0;3176	}3177 3178	/* update rd_point */3179	cq->rd_point = rd_point;3180	hisi_sas_write32(hisi_hba, COMPL_Q_0_RD_PTR + (0x14 * queue), rd_point);3181 3182	return IRQ_HANDLED;3183}3184 3185static irqreturn_t cq_interrupt_v2_hw(int irq_no, void *p)3186{3187	struct hisi_sas_cq *cq = p;3188	struct hisi_hba *hisi_hba = cq->hisi_hba;3189	int queue = cq->id;3190 3191	hisi_sas_write32(hisi_hba, OQ_INT_SRC, 1 << queue);3192 3193	return IRQ_WAKE_THREAD;3194}3195 3196static irqreturn_t sata_int_v2_hw(int irq_no, void *p)3197{3198	struct hisi_sas_phy *phy = p;3199	struct hisi_hba *hisi_hba = phy->hisi_hba;3200	struct asd_sas_phy *sas_phy = &phy->sas_phy;3201	struct device *dev = hisi_hba->dev;3202	struct	hisi_sas_initial_fis *initial_fis;3203	struct dev_to_host_fis *fis;3204	u32 ent_tmp, ent_msk, ent_int, port_id, link_rate, hard_phy_linkrate;3205	irqreturn_t res = IRQ_HANDLED;3206	u8 attached_sas_addr[SAS_ADDR_SIZE] = {0};3207	int phy_no, offset;3208 3209	del_timer(&phy->timer);3210 3211	phy_no = sas_phy->id;3212	initial_fis = &hisi_hba->initial_fis[phy_no];3213	fis = &initial_fis->fis;3214 3215	offset = 4 * (phy_no / 4);3216	ent_msk = hisi_sas_read32(hisi_hba, ENT_INT_SRC_MSK1 + offset);3217	hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1 + offset,3218			 ent_msk | 1 << ((phy_no % 4) * 8));3219 3220	ent_int = hisi_sas_read32(hisi_hba, ENT_INT_SRC1 + offset);3221	ent_tmp = ent_int & (1 << (ENT_INT_SRC1_D2H_FIS_CH1_OFF *3222			     (phy_no % 4)));3223	ent_int >>= ENT_INT_SRC1_D2H_FIS_CH1_OFF * (phy_no % 4);3224	if ((ent_int & ENT_INT_SRC1_D2H_FIS_CH0_MSK) == 0) {3225		dev_warn(dev, "sata int: phy%d did not receive FIS\n", phy_no);3226		res = IRQ_NONE;3227		goto end;3228	}3229 3230	/* check ERR bit of Status Register */3231	if (fis->status & ATA_ERR) {3232		dev_warn(dev, "sata int: phy%d FIS status: 0x%x\n", phy_no,3233			 fis->status);3234		hisi_sas_notify_phy_event(phy, HISI_PHYE_LINK_RESET);3235		res = IRQ_NONE;3236		goto end;3237	}3238 3239	if (unlikely(phy_no == 8)) {3240		u32 port_state = hisi_sas_read32(hisi_hba, PORT_STATE);3241 3242		port_id = (port_state & PORT_STATE_PHY8_PORT_NUM_MSK) >>3243			  PORT_STATE_PHY8_PORT_NUM_OFF;3244		link_rate = (port_state & PORT_STATE_PHY8_CONN_RATE_MSK) >>3245			    PORT_STATE_PHY8_CONN_RATE_OFF;3246	} else {3247		port_id = hisi_sas_read32(hisi_hba, PHY_PORT_NUM_MA);3248		port_id = (port_id >> (4 * phy_no)) & 0xf;3249		link_rate = hisi_sas_read32(hisi_hba, PHY_CONN_RATE);3250		link_rate = (link_rate >> (phy_no * 4)) & 0xf;3251	}3252 3253	if (port_id == 0xf) {3254		dev_err(dev, "sata int: phy%d invalid portid\n", phy_no);3255		res = IRQ_NONE;3256		goto end;3257	}3258 3259	sas_phy->linkrate = link_rate;3260	hard_phy_linkrate = hisi_sas_phy_read32(hisi_hba, phy_no,3261						HARD_PHY_LINKRATE);3262	phy->maximum_linkrate = hard_phy_linkrate & 0xf;3263	phy->minimum_linkrate = (hard_phy_linkrate >> 4) & 0xf;3264 3265	sas_phy->oob_mode = SATA_OOB_MODE;3266	/* Make up some unique SAS address */3267	attached_sas_addr[0] = 0x50;3268	attached_sas_addr[6] = hisi_hba->shost->host_no;3269	attached_sas_addr[7] = phy_no;3270	memcpy(sas_phy->attached_sas_addr, attached_sas_addr, SAS_ADDR_SIZE);3271	memcpy(sas_phy->frame_rcvd, fis, sizeof(struct dev_to_host_fis));3272	dev_info(dev, "sata int phyup: phy%d link_rate=%d\n", phy_no, link_rate);3273	phy->phy_type &= ~(PORT_TYPE_SAS | PORT_TYPE_SATA);3274	phy->port_id = port_id;3275	phy->phy_type |= PORT_TYPE_SATA;3276	phy->phy_attached = 1;3277	phy->identify.device_type = SAS_SATA_DEV;3278	phy->frame_rcvd_size = sizeof(struct dev_to_host_fis);3279	phy->identify.target_port_protocols = SAS_PROTOCOL_SATA;3280	hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP);3281 3282	if (phy->reset_completion)3283		complete(phy->reset_completion);3284end:3285	hisi_sas_write32(hisi_hba, ENT_INT_SRC1 + offset, ent_tmp);3286	hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1 + offset, ent_msk);3287 3288	return res;3289}3290 3291static irq_handler_t phy_interrupts[HISI_SAS_PHY_INT_NR] = {3292	int_phy_updown_v2_hw,3293	int_chnl_int_v2_hw,3294};3295 3296static irq_handler_t fatal_interrupts[HISI_SAS_FATAL_INT_NR] = {3297	fatal_ecc_int_v2_hw,3298	fatal_axi_int_v2_hw3299};3300 3301#define CQ0_IRQ_INDEX (96)3302 3303static int hisi_sas_v2_interrupt_preinit(struct hisi_hba *hisi_hba)3304{3305	struct platform_device *pdev = hisi_hba->platform_dev;3306	struct Scsi_Host *shost = hisi_hba->shost;3307	struct irq_affinity desc = {3308		.pre_vectors = CQ0_IRQ_INDEX,3309		.post_vectors = 16,3310	};3311	int resv = desc.pre_vectors + desc.post_vectors, minvec = resv + 1, nvec;3312 3313	nvec = devm_platform_get_irqs_affinity(pdev, &desc, minvec, 128,3314					       &hisi_hba->irq_map);3315	if (nvec < 0)3316		return nvec;3317 3318	shost->nr_hw_queues = hisi_hba->cq_nvecs = nvec - resv;3319 3320	return 0;3321}3322 3323/*3324 * There is a limitation in the hip06 chipset that we need3325 * to map in all mbigen interrupts, even if they are not used.3326 */3327static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba)3328{3329	struct platform_device *pdev = hisi_hba->platform_dev;3330	struct device *dev = &pdev->dev;3331	int irq, rc = 0;3332	int i, phy_no, fatal_no, queue_no;3333 3334	for (i = 0; i < HISI_SAS_PHY_INT_NR; i++) {3335		irq = hisi_hba->irq_map[i + 1]; /* Phy up/down is irq1 */3336		rc = devm_request_irq(dev, irq, phy_interrupts[i], 0,3337				      DRV_NAME " phy", hisi_hba);3338		if (rc) {3339			dev_err(dev, "irq init: could not request phy interrupt %d, rc=%d\n",3340				irq, rc);3341			rc = -ENOENT;3342			goto err_out;3343		}3344	}3345 3346	for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) {3347		struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];3348 3349		irq = hisi_hba->irq_map[phy_no + 72];3350		rc = devm_request_irq(dev, irq, sata_int_v2_hw, 0,3351				      DRV_NAME " sata", phy);3352		if (rc) {3353			dev_err(dev, "irq init: could not request sata interrupt %d, rc=%d\n",3354				irq, rc);3355			rc = -ENOENT;3356			goto err_out;3357		}3358	}3359 3360	for (fatal_no = 0; fatal_no < HISI_SAS_FATAL_INT_NR; fatal_no++) {3361		irq = hisi_hba->irq_map[fatal_no + 81];3362		rc = devm_request_irq(dev, irq, fatal_interrupts[fatal_no], 0,3363				      DRV_NAME " fatal", hisi_hba);3364		if (rc) {3365			dev_err(dev, "irq init: could not request fatal interrupt %d, rc=%d\n",3366				irq, rc);3367			rc = -ENOENT;3368			goto err_out;3369		}3370	}3371 3372	for (queue_no = 0; queue_no < hisi_hba->cq_nvecs; queue_no++) {3373		struct hisi_sas_cq *cq = &hisi_hba->cq[queue_no];3374 3375		cq->irq_no = hisi_hba->irq_map[queue_no + 96];3376		rc = devm_request_threaded_irq(dev, cq->irq_no,3377					       cq_interrupt_v2_hw,3378					       cq_thread_v2_hw, IRQF_ONESHOT,3379					       DRV_NAME " cq", cq);3380		if (rc) {3381			dev_err(dev, "irq init: could not request cq interrupt %d, rc=%d\n",3382					cq->irq_no, rc);3383			rc = -ENOENT;3384			goto err_out;3385		}3386		cq->irq_mask = irq_get_affinity_mask(cq->irq_no);3387	}3388err_out:3389	return rc;3390}3391 3392static int hisi_sas_v2_init(struct hisi_hba *hisi_hba)3393{3394	int rc;3395 3396	memset(hisi_hba->sata_dev_bitmap, 0, sizeof(hisi_hba->sata_dev_bitmap));3397 3398	rc = hw_init_v2_hw(hisi_hba);3399	if (rc)3400		return rc;3401 3402	rc = interrupt_init_v2_hw(hisi_hba);3403	if (rc)3404		return rc;3405 3406	return 0;3407}3408 3409static void interrupt_disable_v2_hw(struct hisi_hba *hisi_hba)3410{3411	struct platform_device *pdev = hisi_hba->platform_dev;3412	int i;3413 3414	for (i = 0; i < hisi_hba->queue_count; i++)3415		hisi_sas_write32(hisi_hba, OQ0_INT_SRC_MSK + 0x4 * i, 0x1);3416 3417	hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, 0xffffffff);3418	hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK2, 0xffffffff);3419	hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xffffffff);3420	hisi_sas_write32(hisi_hba, SAS_ECC_INTR_MSK, 0xffffffff);3421 3422	for (i = 0; i < hisi_hba->n_phy; i++) {3423		hisi_sas_phy_write32(hisi_hba, i, CHL_INT1_MSK, 0xffffffff);3424		hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0xffffffff);3425	}3426 3427	for (i = 0; i < 128; i++)3428		synchronize_irq(platform_get_irq(pdev, i));3429}3430 3431 3432static u32 get_phys_state_v2_hw(struct hisi_hba *hisi_hba)3433{3434	return hisi_sas_read32(hisi_hba, PHY_STATE);3435}3436 3437static int soft_reset_v2_hw(struct hisi_hba *hisi_hba)3438{3439	struct device *dev = hisi_hba->dev;3440	int rc, cnt;3441 3442	interrupt_disable_v2_hw(hisi_hba);3443	hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, 0x0);3444 3445	hisi_sas_stop_phys(hisi_hba);3446 3447	mdelay(10);3448 3449	hisi_sas_write32(hisi_hba, AXI_MASTER_CFG_BASE + AM_CTRL_GLOBAL, 0x1);3450 3451	/* wait until bus idle */3452	cnt = 0;3453	while (1) {3454		u32 status = hisi_sas_read32_relaxed(hisi_hba,3455				AXI_MASTER_CFG_BASE + AM_CURR_TRANS_RETURN);3456 3457		if (status == 0x3)3458			break;3459 3460		udelay(10);3461		if (cnt++ > 10) {3462			dev_err(dev, "wait axi bus state to idle timeout!\n");3463			return -1;3464		}3465	}3466 3467	hisi_sas_init_mem(hisi_hba);3468 3469	rc = hw_init_v2_hw(hisi_hba);3470	if (rc)3471		return rc;3472 3473	phys_reject_stp_links_v2_hw(hisi_hba);3474 3475	return 0;3476}3477 3478static int write_gpio_v2_hw(struct hisi_hba *hisi_hba, u8 reg_type,3479			u8 reg_index, u8 reg_count, u8 *write_data)3480{3481	struct device *dev = hisi_hba->dev;3482	int phy_no, count;3483 3484	if (!hisi_hba->sgpio_regs)3485		return -EOPNOTSUPP;3486 3487	switch (reg_type) {3488	case SAS_GPIO_REG_TX:3489		count = reg_count * 4;3490		count = min(count, hisi_hba->n_phy);3491 3492		for (phy_no = 0; phy_no < count; phy_no++) {3493			/*3494			 * GPIO_TX[n] register has the highest numbered drive3495			 * of the four in the first byte and the lowest3496			 * numbered drive in the fourth byte.3497			 * See SFF-8485 Rev. 0.7 Table 24.3498			 */3499			void __iomem  *reg_addr = hisi_hba->sgpio_regs +3500					reg_index * 4 + phy_no;3501			int data_idx = phy_no + 3 - (phy_no % 4) * 2;3502 3503			writeb(write_data[data_idx], reg_addr);3504		}3505 3506		break;3507	default:3508		dev_err(dev, "write gpio: unsupported or bad reg type %d\n",3509			reg_type);3510		return -EINVAL;3511	}3512 3513	return 0;3514}3515 3516static void wait_cmds_complete_timeout_v2_hw(struct hisi_hba *hisi_hba,3517					     int delay_ms, int timeout_ms)3518{3519	struct device *dev = hisi_hba->dev;3520	int entries, entries_old = 0, time;3521 3522	for (time = 0; time < timeout_ms; time += delay_ms) {3523		entries = hisi_sas_read32(hisi_hba, CQE_SEND_CNT);3524		if (entries == entries_old)3525			break;3526 3527		entries_old = entries;3528		msleep(delay_ms);3529	}3530 3531	if (time >= timeout_ms) {3532		dev_dbg(dev, "Wait commands complete timeout!\n");3533		return;3534	}3535 3536	dev_dbg(dev, "wait commands complete %dms\n", time);3537 3538}3539 3540static struct attribute *host_v2_hw_attrs[] = {3541	&dev_attr_phy_event_threshold.attr,3542	NULL3543};3544 3545ATTRIBUTE_GROUPS(host_v2_hw);3546 3547static const struct attribute_group *sdev_groups_v2_hw[] = {3548	&sas_ata_sdev_attr_group,3549	NULL3550};3551 3552static void map_queues_v2_hw(struct Scsi_Host *shost)3553{3554	struct hisi_hba *hisi_hba = shost_priv(shost);3555	struct blk_mq_queue_map *qmap = &shost->tag_set.map[HCTX_TYPE_DEFAULT];3556	const struct cpumask *mask;3557	unsigned int queue, cpu;3558 3559	for (queue = 0; queue < qmap->nr_queues; queue++) {3560		mask = irq_get_affinity_mask(hisi_hba->irq_map[96 + queue]);3561		if (!mask)3562			continue;3563 3564		for_each_cpu(cpu, mask)3565			qmap->mq_map[cpu] = qmap->queue_offset + queue;3566	}3567}3568 3569static const struct scsi_host_template sht_v2_hw = {3570	LIBSAS_SHT_BASE_NO_SLAVE_INIT3571	.device_configure	= hisi_sas_device_configure,3572	.scan_finished		= hisi_sas_scan_finished,3573	.scan_start		= hisi_sas_scan_start,3574	.sg_tablesize		= HISI_SAS_SGE_PAGE_CNT,3575	.slave_alloc		= hisi_sas_slave_alloc,3576	.shost_groups		= host_v2_hw_groups,3577	.sdev_groups		= sdev_groups_v2_hw,3578	.host_reset		= hisi_sas_host_reset,3579	.map_queues		= map_queues_v2_hw,3580	.host_tagset		= 1,3581};3582 3583static const struct hisi_sas_hw hisi_sas_v2_hw = {3584	.hw_init = hisi_sas_v2_init,3585	.interrupt_preinit = hisi_sas_v2_interrupt_preinit,3586	.setup_itct = setup_itct_v2_hw,3587	.slot_index_alloc = slot_index_alloc_quirk_v2_hw,3588	.alloc_dev = alloc_dev_quirk_v2_hw,3589	.sl_notify_ssp = sl_notify_ssp_v2_hw,3590	.get_wideport_bitmap = get_wideport_bitmap_v2_hw,3591	.clear_itct = clear_itct_v2_hw,3592	.free_device = free_device_v2_hw,3593	.prep_smp = prep_smp_v2_hw,3594	.prep_ssp = prep_ssp_v2_hw,3595	.prep_stp = prep_ata_v2_hw,3596	.prep_abort = prep_abort_v2_hw,3597	.start_delivery = start_delivery_v2_hw,3598	.phys_init = phys_init_v2_hw,3599	.phy_start = start_phy_v2_hw,3600	.phy_disable = disable_phy_v2_hw,3601	.phy_hard_reset = phy_hard_reset_v2_hw,3602	.get_events = phy_get_events_v2_hw,3603	.phy_set_linkrate = phy_set_linkrate_v2_hw,3604	.phy_get_max_linkrate = phy_get_max_linkrate_v2_hw,3605	.complete_hdr_size = sizeof(struct hisi_sas_complete_v2_hdr),3606	.soft_reset = soft_reset_v2_hw,3607	.get_phys_state = get_phys_state_v2_hw,3608	.write_gpio = write_gpio_v2_hw,3609	.wait_cmds_complete_timeout = wait_cmds_complete_timeout_v2_hw,3610	.sht = &sht_v2_hw,3611};3612 3613static int hisi_sas_v2_probe(struct platform_device *pdev)3614{3615	return hisi_sas_probe(pdev, &hisi_sas_v2_hw);3616}3617 3618static const struct of_device_id sas_v2_of_match[] = {3619	{ .compatible = "hisilicon,hip06-sas-v2",},3620	{ .compatible = "hisilicon,hip07-sas-v2",},3621	{},3622};3623MODULE_DEVICE_TABLE(of, sas_v2_of_match);3624 3625static const struct acpi_device_id sas_v2_acpi_match[] = {3626	{ "HISI0162", 0 },3627	{ }3628};3629 3630MODULE_DEVICE_TABLE(acpi, sas_v2_acpi_match);3631 3632static struct platform_driver hisi_sas_v2_driver = {3633	.probe = hisi_sas_v2_probe,3634	.remove_new = hisi_sas_remove,3635	.driver = {3636		.name = DRV_NAME,3637		.of_match_table = sas_v2_of_match,3638		.acpi_match_table = ACPI_PTR(sas_v2_acpi_match),3639	},3640};3641 3642module_platform_driver(hisi_sas_v2_driver);3643 3644MODULE_LICENSE("GPL");3645MODULE_AUTHOR("John Garry <john.garry@huawei.com>");3646MODULE_DESCRIPTION("HISILICON SAS controller v2 hw driver");3647MODULE_ALIAS("platform:" DRV_NAME);3648