xref: /linux/drivers/scsi/hisi_sas/hisi_sas.h (revision d2fc401e47529d9ffd2673a5395d56002e31ad98)
1e8899fadSJohn Garry /*
2e8899fadSJohn Garry  * Copyright (c) 2015 Linaro Ltd.
3e8899fadSJohn Garry  * Copyright (c) 2015 Hisilicon Limited.
4e8899fadSJohn Garry  *
5e8899fadSJohn Garry  * This program is free software; you can redistribute it and/or modify
6e8899fadSJohn Garry  * it under the terms of the GNU General Public License as published by
7e8899fadSJohn Garry  * the Free Software Foundation; either version 2 of the License, or
8e8899fadSJohn Garry  * (at your option) any later version.
9e8899fadSJohn Garry  *
10e8899fadSJohn Garry  */
11e8899fadSJohn Garry 
12e8899fadSJohn Garry #ifndef _HISI_SAS_H_
13e8899fadSJohn Garry #define _HISI_SAS_H_
14e8899fadSJohn Garry 
154d558c77SJohn Garry #include <linux/acpi.h>
163bc45af8SJohn Garry #include <linux/clk.h>
17e8899fadSJohn Garry #include <linux/dmapool.h>
18a25d0d3dSXiang Chen #include <linux/iopoll.h>
19e8899fadSJohn Garry #include <linux/mfd/syscon.h>
20e8899fadSJohn Garry #include <linux/module.h>
21e8899fadSJohn Garry #include <linux/of_address.h>
2211b75249SJohn Garry #include <linux/pci.h>
23e8899fadSJohn Garry #include <linux/platform_device.h>
244d558c77SJohn Garry #include <linux/property.h>
25e8899fadSJohn Garry #include <linux/regmap.h>
266f2ff1a1SJohn Garry #include <scsi/sas_ata.h>
27e8899fadSJohn Garry #include <scsi/libsas.h>
28e8899fadSJohn Garry 
297eb7869fSJohn Garry #define HISI_SAS_MAX_PHYS	9
306be6de18SJohn Garry #define HISI_SAS_MAX_QUEUES	32
316be6de18SJohn Garry #define HISI_SAS_QUEUE_SLOTS 512
323297ded1SXiang Chen #define HISI_SAS_MAX_ITCT_ENTRIES 1024
337eb7869fSJohn Garry #define HISI_SAS_MAX_DEVICES HISI_SAS_MAX_ITCT_ENTRIES
3406ec0fb9SXiang Chen #define HISI_SAS_RESET_BIT	0
35917d3bdaSXiaofei Tan #define HISI_SAS_REJECT_CMD_BIT	1
367eb7869fSJohn Garry 
37f557e32cSXiaofei Tan #define HISI_SAS_STATUS_BUF_SZ (sizeof(struct hisi_sas_status_buffer))
38f557e32cSXiaofei Tan #define HISI_SAS_COMMAND_TABLE_SZ (sizeof(union hisi_sas_command_table))
39f557e32cSXiaofei Tan 
40f557e32cSXiaofei Tan #define hisi_sas_status_buf_addr(buf) \
41f557e32cSXiaofei Tan 	(buf + offsetof(struct hisi_sas_slot_buf_table, status_buffer))
42f557e32cSXiaofei Tan #define hisi_sas_status_buf_addr_mem(slot) hisi_sas_status_buf_addr(slot->buf)
43f557e32cSXiaofei Tan #define hisi_sas_status_buf_addr_dma(slot) \
44f557e32cSXiaofei Tan 	hisi_sas_status_buf_addr(slot->buf_dma)
45f557e32cSXiaofei Tan 
46f557e32cSXiaofei Tan #define hisi_sas_cmd_hdr_addr(buf) \
47f557e32cSXiaofei Tan 	(buf + offsetof(struct hisi_sas_slot_buf_table, command_header))
48f557e32cSXiaofei Tan #define hisi_sas_cmd_hdr_addr_mem(slot) hisi_sas_cmd_hdr_addr(slot->buf)
49f557e32cSXiaofei Tan #define hisi_sas_cmd_hdr_addr_dma(slot) hisi_sas_cmd_hdr_addr(slot->buf_dma)
50f557e32cSXiaofei Tan 
51f557e32cSXiaofei Tan #define hisi_sas_sge_addr(buf) \
52f557e32cSXiaofei Tan 	(buf + offsetof(struct hisi_sas_slot_buf_table, sge_page))
53f557e32cSXiaofei Tan #define hisi_sas_sge_addr_mem(slot) hisi_sas_sge_addr(slot->buf)
54f557e32cSXiaofei Tan #define hisi_sas_sge_addr_dma(slot) hisi_sas_sge_addr(slot->buf_dma)
556be6de18SJohn Garry 
5642e7a693SJohn Garry #define HISI_SAS_MAX_SSP_RESP_SZ (sizeof(struct ssp_frame_hdr) + 1024)
5766ee999bSJohn Garry #define HISI_SAS_MAX_SMP_RESP_SZ 1028
586f2ff1a1SJohn Garry #define HISI_SAS_MAX_STP_RESP_SZ 28
5942e7a693SJohn Garry 
6098bf39fcSJohn Garry #define DEV_IS_EXPANDER(type) \
6198bf39fcSJohn Garry 	((type == SAS_EDGE_EXPANDER_DEVICE) || \
6298bf39fcSJohn Garry 	(type == SAS_FANOUT_EXPANDER_DEVICE))
6398bf39fcSJohn Garry 
646c7bb8a1SXiang Chen #define HISI_SAS_SATA_PROTOCOL_NONDATA		0x1
656c7bb8a1SXiang Chen #define HISI_SAS_SATA_PROTOCOL_PIO			0x2
666c7bb8a1SXiang Chen #define HISI_SAS_SATA_PROTOCOL_DMA			0x4
676c7bb8a1SXiang Chen #define HISI_SAS_SATA_PROTOCOL_FPDMA		0x8
686c7bb8a1SXiang Chen #define HISI_SAS_SATA_PROTOCOL_ATAPI		0x10
696c7bb8a1SXiang Chen 
70abda97c2SJohn Garry struct hisi_hba;
71af740dbeSJohn Garry 
7207d78592SJohn Garry enum {
7307d78592SJohn Garry 	PORT_TYPE_SAS = (1U << 1),
7407d78592SJohn Garry 	PORT_TYPE_SATA = (1U << 0),
7507d78592SJohn Garry };
7607d78592SJohn Garry 
77af740dbeSJohn Garry enum dev_status {
78af740dbeSJohn Garry 	HISI_SAS_DEV_NORMAL,
79af740dbeSJohn Garry 	HISI_SAS_DEV_EH,
80af740dbeSJohn Garry };
81abda97c2SJohn Garry 
82441c2740SJohn Garry enum {
83441c2740SJohn Garry 	HISI_SAS_INT_ABT_CMD = 0,
84441c2740SJohn Garry 	HISI_SAS_INT_ABT_DEV = 1,
85441c2740SJohn Garry };
86441c2740SJohn Garry 
87abda97c2SJohn Garry enum hisi_sas_dev_type {
88abda97c2SJohn Garry 	HISI_SAS_DEV_TYPE_STP = 0,
89abda97c2SJohn Garry 	HISI_SAS_DEV_TYPE_SSP,
90abda97c2SJohn Garry 	HISI_SAS_DEV_TYPE_SATA,
91abda97c2SJohn Garry };
92abda97c2SJohn Garry 
932b383351SJohn Garry struct hisi_sas_hw_error {
942b383351SJohn Garry 	u32 irq_msk;
952b383351SJohn Garry 	u32 msk;
962b383351SJohn Garry 	int shift;
972b383351SJohn Garry 	const char *msg;
982b383351SJohn Garry 	int reg;
99729428caSShiju Jose 	const struct hisi_sas_hw_error *sub;
1002b383351SJohn Garry };
1012b383351SJohn Garry 
102e402acdbSXiaofei Tan struct hisi_sas_rst {
103e402acdbSXiaofei Tan 	struct hisi_hba *hisi_hba;
104e402acdbSXiaofei Tan 	struct completion *completion;
105e402acdbSXiaofei Tan 	struct work_struct work;
106e402acdbSXiaofei Tan 	bool done;
107e402acdbSXiaofei Tan };
108e402acdbSXiaofei Tan 
109e402acdbSXiaofei Tan #define HISI_SAS_RST_WORK_INIT(r, c) \
110e402acdbSXiaofei Tan 	{	.hisi_hba = hisi_hba, \
111e402acdbSXiaofei Tan 		.completion = &c, \
112e402acdbSXiaofei Tan 		.work = __WORK_INITIALIZER(r.work, \
113e402acdbSXiaofei Tan 				hisi_sas_sync_rst_work_handler), \
114e402acdbSXiaofei Tan 		.done = false, \
115e402acdbSXiaofei Tan 		}
116e402acdbSXiaofei Tan 
117e402acdbSXiaofei Tan #define HISI_SAS_DECLARE_RST_WORK_ON_STACK(r) \
118e402acdbSXiaofei Tan 	DECLARE_COMPLETION_ONSTACK(c); \
119e402acdbSXiaofei Tan 	DECLARE_WORK(w, hisi_sas_sync_rst_work_handler); \
120e402acdbSXiaofei Tan 	struct hisi_sas_rst r = HISI_SAS_RST_WORK_INIT(r, c)
121e402acdbSXiaofei Tan 
122e402acdbSXiaofei Tan enum hisi_sas_bit_err_type {
123e402acdbSXiaofei Tan 	HISI_SAS_ERR_SINGLE_BIT_ECC = 0x0,
124e402acdbSXiaofei Tan 	HISI_SAS_ERR_MULTI_BIT_ECC = 0x1,
125e402acdbSXiaofei Tan };
126e402acdbSXiaofei Tan 
127e537b62bSXiaofei Tan enum hisi_sas_phy_event {
128e537b62bSXiaofei Tan 	HISI_PHYE_PHY_UP   = 0U,
129057c3d1fSXiaofei Tan 	HISI_PHYE_LINK_RESET,
130e537b62bSXiaofei Tan 	HISI_PHYES_NUM,
131e537b62bSXiaofei Tan };
132e537b62bSXiaofei Tan 
1337eb7869fSJohn Garry struct hisi_sas_phy {
134e537b62bSXiaofei Tan 	struct work_struct	works[HISI_PHYES_NUM];
135976867e6SJohn Garry 	struct hisi_hba	*hisi_hba;
136976867e6SJohn Garry 	struct hisi_sas_port	*port;
1377eb7869fSJohn Garry 	struct asd_sas_phy	sas_phy;
138976867e6SJohn Garry 	struct sas_identify	identify;
1393e1fb1b8SXiang Chen 	struct completion *reset_completion;
1403e1fb1b8SXiang Chen 	spinlock_t lock;
141976867e6SJohn Garry 	u64		port_id; /* from hw */
142976867e6SJohn Garry 	u64		frame_rcvd_size;
143976867e6SJohn Garry 	u8		frame_rcvd[32];
144976867e6SJohn Garry 	u8		phy_attached;
1453e1fb1b8SXiang Chen 	u8		in_reset;
1463e1fb1b8SXiang Chen 	u8		reserved[2];
147d0ef10c9SJohn Garry 	u32		phy_type;
148976867e6SJohn Garry 	enum sas_linkrate	minimum_linkrate;
149976867e6SJohn Garry 	enum sas_linkrate	maximum_linkrate;
1507eb7869fSJohn Garry };
1517eb7869fSJohn Garry 
1527eb7869fSJohn Garry struct hisi_sas_port {
1537eb7869fSJohn Garry 	struct asd_sas_port	sas_port;
154976867e6SJohn Garry 	u8	port_attached;
155976867e6SJohn Garry 	u8	id; /* from hw */
1567eb7869fSJohn Garry };
1577eb7869fSJohn Garry 
1589101a079SJohn Garry struct hisi_sas_cq {
1599101a079SJohn Garry 	struct hisi_hba *hisi_hba;
160d177c408SJohn Garry 	struct tasklet_struct tasklet;
161e6c346f3SJohn Garry 	int	rd_point;
1629101a079SJohn Garry 	int	id;
1639101a079SJohn Garry };
1649101a079SJohn Garry 
1654fde02adSJohn Garry struct hisi_sas_dq {
1664fde02adSJohn Garry 	struct hisi_hba *hisi_hba;
167fa222db0SXiang Chen 	struct list_head list;
168b1a49412SXiang Chen 	spinlock_t lock;
1694fde02adSJohn Garry 	int	wr_point;
1704fde02adSJohn Garry 	int	id;
1714fde02adSJohn Garry };
1724fde02adSJohn Garry 
173af740dbeSJohn Garry struct hisi_sas_device {
174abda97c2SJohn Garry 	struct hisi_hba		*hisi_hba;
175abda97c2SJohn Garry 	struct domain_device	*sas_device;
176640acc9aSXiang Chen 	struct completion *completion;
177b1a49412SXiang Chen 	struct hisi_sas_dq	*dq;
178405314dfSJohn Garry 	struct list_head	list;
179ad604832SJohn Garry 	enum sas_device_type	dev_type;
180ad604832SJohn Garry 	int device_id;
18132ccba52SXiaofei Tan 	int sata_idx;
182ad604832SJohn Garry 	u8 dev_status;
183af740dbeSJohn Garry };
184af740dbeSJohn Garry 
18578bd2b4fSXiaofei Tan struct hisi_sas_tmf_task {
186b09fcd09SXiaofei Tan 	int force_phy;
187b09fcd09SXiaofei Tan 	int phy_id;
18878bd2b4fSXiaofei Tan 	u8 tmf;
18978bd2b4fSXiaofei Tan 	u16 tag_of_task_to_be_managed;
19078bd2b4fSXiaofei Tan };
19178bd2b4fSXiaofei Tan 
1926be6de18SJohn Garry struct hisi_sas_slot {
19342e7a693SJohn Garry 	struct list_head entry;
194fa222db0SXiang Chen 	struct list_head delivery;
19542e7a693SJohn Garry 	struct sas_task *task;
19642e7a693SJohn Garry 	struct hisi_sas_port	*port;
19742e7a693SJohn Garry 	u64	n_elem;
19842e7a693SJohn Garry 	int	dlvry_queue;
19942e7a693SJohn Garry 	int	dlvry_queue_slot;
20027a3f229SJohn Garry 	int	cmplt_queue;
20127a3f229SJohn Garry 	int	cmplt_queue_slot;
20242e7a693SJohn Garry 	int	idx;
203cac9b2a2SJohn Garry 	int	abort;
204fa222db0SXiang Chen 	int	ready;
205f557e32cSXiaofei Tan 	void	*buf;
206f557e32cSXiaofei Tan 	dma_addr_t buf_dma;
20742e7a693SJohn Garry 	void	*cmd_hdr;
20842e7a693SJohn Garry 	dma_addr_t cmd_hdr_dma;
209cac9b2a2SJohn Garry 	struct work_struct abort_slot;
2100844a3ffSJohn Garry 	struct timer_list internal_abort_timer;
211cd938e53SXiang Chen 	bool is_internal;
21278bd2b4fSXiaofei Tan 	struct hisi_sas_tmf_task *tmf;
2136be6de18SJohn Garry };
2146be6de18SJohn Garry 
2157eb7869fSJohn Garry struct hisi_sas_hw {
2168ff1d571SJohn Garry 	int (*hw_init)(struct hisi_hba *hisi_hba);
217abda97c2SJohn Garry 	void (*setup_itct)(struct hisi_hba *hisi_hba,
218abda97c2SJohn Garry 			   struct hisi_sas_device *device);
219685b6d6eSJohn Garry 	int (*slot_index_alloc)(struct hisi_hba *hisi_hba, int *slot_idx,
220685b6d6eSJohn Garry 				struct domain_device *device);
221685b6d6eSJohn Garry 	struct hisi_sas_device *(*alloc_dev)(struct domain_device *device);
22266139921SJohn Garry 	void (*sl_notify)(struct hisi_hba *hisi_hba, int phy_no);
223b1a49412SXiang Chen 	int (*get_free_slot)(struct hisi_hba *hisi_hba, struct hisi_sas_dq *dq);
224b1a49412SXiang Chen 	void (*start_delivery)(struct hisi_sas_dq *dq);
225a2b3820bSXiang Chen 	void (*prep_ssp)(struct hisi_hba *hisi_hba,
22678bd2b4fSXiaofei Tan 			struct hisi_sas_slot *slot);
227a2b3820bSXiang Chen 	void (*prep_smp)(struct hisi_hba *hisi_hba,
22866ee999bSJohn Garry 			struct hisi_sas_slot *slot);
229a2b3820bSXiang Chen 	void (*prep_stp)(struct hisi_hba *hisi_hba,
2306f2ff1a1SJohn Garry 			struct hisi_sas_slot *slot);
231a2b3820bSXiang Chen 	void (*prep_abort)(struct hisi_hba *hisi_hba,
232441c2740SJohn Garry 			  struct hisi_sas_slot *slot,
233441c2740SJohn Garry 			  int device_id, int abort_flag, int tag_to_abort);
23427a3f229SJohn Garry 	int (*slot_complete)(struct hisi_hba *hisi_hba,
235405314dfSJohn Garry 			     struct hisi_sas_slot *slot);
236396b8044SJohn Garry 	void (*phys_init)(struct hisi_hba *hisi_hba);
2371eb8eeacSXiang Chen 	void (*phy_start)(struct hisi_hba *hisi_hba, int phy_no);
238e4189d53SJohn Garry 	void (*phy_disable)(struct hisi_hba *hisi_hba, int phy_no);
239e4189d53SJohn Garry 	void (*phy_hard_reset)(struct hisi_hba *hisi_hba, int phy_no);
240c52108c6SXiaofei Tan 	void (*get_events)(struct hisi_hba *hisi_hba, int phy_no);
2412ae75787SXiang Chen 	void (*phy_set_linkrate)(struct hisi_hba *hisi_hba, int phy_no,
2422ae75787SXiang Chen 			struct sas_phy_linkrates *linkrates);
2432ae75787SXiang Chen 	enum sas_linkrate (*phy_get_max_linkrate)(void);
2440258141aSXiaofei Tan 	void (*clear_itct)(struct hisi_hba *hisi_hba,
24527a3f229SJohn Garry 			    struct hisi_sas_device *dev);
2460258141aSXiaofei Tan 	void (*free_device)(struct hisi_sas_device *sas_dev);
247184a4635SJohn Garry 	int (*get_wideport_bitmap)(struct hisi_hba *hisi_hba, int port_id);
248d30ff263SXiang Chen 	void (*dereg_device)(struct hisi_hba *hisi_hba,
249d30ff263SXiang Chen 				struct domain_device *device);
25006ec0fb9SXiang Chen 	int (*soft_reset)(struct hisi_hba *hisi_hba);
251917d3bdaSXiaofei Tan 	u32 (*get_phys_state)(struct hisi_hba *hisi_hba);
2526379c560SXiaofei Tan 	int (*write_gpio)(struct hisi_hba *hisi_hba, u8 reg_type,
2536379c560SXiaofei Tan 				u8 reg_index, u8 reg_count, u8 *write_data);
254a865ae14SXiaofei Tan 	void (*wait_cmds_complete_timeout)(struct hisi_hba *hisi_hba,
255a865ae14SXiaofei Tan 					   int delay_ms, int timeout_ms);
256a8d547bdSJohn Garry 	int max_command_entries;
2576be6de18SJohn Garry 	int complete_hdr_size;
258235bfc7fSXiang Chen 	struct scsi_host_template *sht;
2597eb7869fSJohn Garry };
2607eb7869fSJohn Garry 
2617eb7869fSJohn Garry struct hisi_hba {
2627eb7869fSJohn Garry 	/* This must be the first element, used by SHOST_TO_SAS_HA */
2637eb7869fSJohn Garry 	struct sas_ha_struct *p;
2647eb7869fSJohn Garry 
26511b75249SJohn Garry 	struct platform_device *platform_dev;
26611b75249SJohn Garry 	struct pci_dev *pci_dev;
26711b75249SJohn Garry 	struct device *dev;
26811b75249SJohn Garry 
269e26b2f40SJohn Garry 	void __iomem *regs;
2706379c560SXiaofei Tan 	void __iomem *sgpio_regs;
271e26b2f40SJohn Garry 	struct regmap *ctrl;
272e26b2f40SJohn Garry 	u32 ctrl_reset_reg;
273e26b2f40SJohn Garry 	u32 ctrl_reset_sts_reg;
274e26b2f40SJohn Garry 	u32 ctrl_clock_ena_reg;
2753bc45af8SJohn Garry 	u32 refclk_frequency_mhz;
2767eb7869fSJohn Garry 	u8 sas_addr[SAS_ADDR_SIZE];
2777eb7869fSJohn Garry 
2787eb7869fSJohn Garry 	int n_phy;
279fa42d80dSJohn Garry 	spinlock_t lock;
280*d2fc401eSXiaofei Tan 	struct semaphore sem;
2817eb7869fSJohn Garry 
282fa42d80dSJohn Garry 	struct timer_list timer;
2837e9080e1SJohn Garry 	struct workqueue_struct *wq;
284257efd1fSJohn Garry 
285257efd1fSJohn Garry 	int slot_index_count;
286fa3be0f2SXiang Chen 	int last_slot_index;
2871b865185SXiang Chen 	int last_dev_id;
288257efd1fSJohn Garry 	unsigned long *slot_index_tags;
289c7b9d369SXiaofei Tan 	unsigned long reject_stp_links_msk;
290257efd1fSJohn Garry 
2917eb7869fSJohn Garry 	/* SCSI/SAS glue */
2927eb7869fSJohn Garry 	struct sas_ha_struct sha;
2937eb7869fSJohn Garry 	struct Scsi_Host *shost;
2949101a079SJohn Garry 
2959101a079SJohn Garry 	struct hisi_sas_cq cq[HISI_SAS_MAX_QUEUES];
2964fde02adSJohn Garry 	struct hisi_sas_dq dq[HISI_SAS_MAX_QUEUES];
2977eb7869fSJohn Garry 	struct hisi_sas_phy phy[HISI_SAS_MAX_PHYS];
2987eb7869fSJohn Garry 	struct hisi_sas_port port[HISI_SAS_MAX_PHYS];
299e26b2f40SJohn Garry 
300e26b2f40SJohn Garry 	int	queue_count;
3016be6de18SJohn Garry 
302f557e32cSXiaofei Tan 	struct dma_pool *buffer_pool;
303af740dbeSJohn Garry 	struct hisi_sas_device	devices[HISI_SAS_MAX_DEVICES];
3046be6de18SJohn Garry 	struct hisi_sas_cmd_hdr	*cmd_hdr[HISI_SAS_MAX_QUEUES];
3056be6de18SJohn Garry 	dma_addr_t cmd_hdr_dma[HISI_SAS_MAX_QUEUES];
3066be6de18SJohn Garry 	void *complete_hdr[HISI_SAS_MAX_QUEUES];
3076be6de18SJohn Garry 	dma_addr_t complete_hdr_dma[HISI_SAS_MAX_QUEUES];
3086be6de18SJohn Garry 	struct hisi_sas_initial_fis *initial_fis;
3096be6de18SJohn Garry 	dma_addr_t initial_fis_dma;
3106be6de18SJohn Garry 	struct hisi_sas_itct *itct;
3116be6de18SJohn Garry 	dma_addr_t itct_dma;
3126be6de18SJohn Garry 	struct hisi_sas_iost *iost;
3136be6de18SJohn Garry 	dma_addr_t iost_dma;
3146be6de18SJohn Garry 	struct hisi_sas_breakpoint *breakpoint;
3156be6de18SJohn Garry 	dma_addr_t breakpoint_dma;
3166be6de18SJohn Garry 	struct hisi_sas_breakpoint *sata_breakpoint;
3176be6de18SJohn Garry 	dma_addr_t sata_breakpoint_dma;
3186be6de18SJohn Garry 	struct hisi_sas_slot	*slot_info;
31906ec0fb9SXiang Chen 	unsigned long flags;
3207eb7869fSJohn Garry 	const struct hisi_sas_hw *hw;	/* Low level hw interface */
32132ccba52SXiaofei Tan 	unsigned long sata_dev_bitmap[BITS_TO_LONGS(HISI_SAS_MAX_DEVICES)];
32206ec0fb9SXiang Chen 	struct work_struct rst_work;
3237eb7869fSJohn Garry };
3247eb7869fSJohn Garry 
325c799d6bdSJohn Garry /* Generic HW DMA host memory structures */
326c799d6bdSJohn Garry /* Delivery queue header */
327c799d6bdSJohn Garry struct hisi_sas_cmd_hdr {
328c799d6bdSJohn Garry 	/* dw0 */
329c799d6bdSJohn Garry 	__le32 dw0;
330c799d6bdSJohn Garry 
331c799d6bdSJohn Garry 	/* dw1 */
332c799d6bdSJohn Garry 	__le32 dw1;
333c799d6bdSJohn Garry 
334c799d6bdSJohn Garry 	/* dw2 */
335c799d6bdSJohn Garry 	__le32 dw2;
336c799d6bdSJohn Garry 
337c799d6bdSJohn Garry 	/* dw3 */
338c799d6bdSJohn Garry 	__le32 transfer_tags;
339c799d6bdSJohn Garry 
340c799d6bdSJohn Garry 	/* dw4 */
341c799d6bdSJohn Garry 	__le32 data_transfer_len;
342c799d6bdSJohn Garry 
343c799d6bdSJohn Garry 	/* dw5 */
344c799d6bdSJohn Garry 	__le32 first_burst_num;
345c799d6bdSJohn Garry 
346c799d6bdSJohn Garry 	/* dw6 */
347c799d6bdSJohn Garry 	__le32 sg_len;
348c799d6bdSJohn Garry 
349c799d6bdSJohn Garry 	/* dw7 */
350c799d6bdSJohn Garry 	__le32 dw7;
351c799d6bdSJohn Garry 
352c799d6bdSJohn Garry 	/* dw8-9 */
353c799d6bdSJohn Garry 	__le64 cmd_table_addr;
354c799d6bdSJohn Garry 
355c799d6bdSJohn Garry 	/* dw10-11 */
356c799d6bdSJohn Garry 	__le64 sts_buffer_addr;
357c799d6bdSJohn Garry 
358c799d6bdSJohn Garry 	/* dw12-13 */
359c799d6bdSJohn Garry 	__le64 prd_table_addr;
360c799d6bdSJohn Garry 
361c799d6bdSJohn Garry 	/* dw14-15 */
362c799d6bdSJohn Garry 	__le64 dif_prd_table_addr;
363c799d6bdSJohn Garry };
364c799d6bdSJohn Garry 
365c799d6bdSJohn Garry struct hisi_sas_itct {
366c799d6bdSJohn Garry 	__le64 qw0;
367c799d6bdSJohn Garry 	__le64 sas_addr;
368c799d6bdSJohn Garry 	__le64 qw2;
369c799d6bdSJohn Garry 	__le64 qw3;
370281e3bf6SJohn Garry 	__le64 qw4_15[12];
371c799d6bdSJohn Garry };
372c799d6bdSJohn Garry 
373c799d6bdSJohn Garry struct hisi_sas_iost {
374c799d6bdSJohn Garry 	__le64 qw0;
375c799d6bdSJohn Garry 	__le64 qw1;
376c799d6bdSJohn Garry 	__le64 qw2;
377c799d6bdSJohn Garry 	__le64 qw3;
378c799d6bdSJohn Garry };
379c799d6bdSJohn Garry 
380c799d6bdSJohn Garry struct hisi_sas_err_record {
3818d1eee7dSJohn Garry 	u32	data[4];
382c799d6bdSJohn Garry };
383c799d6bdSJohn Garry 
384c799d6bdSJohn Garry struct hisi_sas_initial_fis {
385c799d6bdSJohn Garry 	struct hisi_sas_err_record err_record;
386c799d6bdSJohn Garry 	struct dev_to_host_fis fis;
387c799d6bdSJohn Garry 	u32 rsvd[3];
388c799d6bdSJohn Garry };
389c799d6bdSJohn Garry 
390c799d6bdSJohn Garry struct hisi_sas_breakpoint {
3913297ded1SXiang Chen 	u8	data[128];
3923297ded1SXiang Chen };
3933297ded1SXiang Chen 
3943297ded1SXiang Chen struct hisi_sas_sata_breakpoint {
3953297ded1SXiang Chen 	struct hisi_sas_breakpoint tag[32];
396c799d6bdSJohn Garry };
397c799d6bdSJohn Garry 
398c799d6bdSJohn Garry struct hisi_sas_sge {
399c799d6bdSJohn Garry 	__le64 addr;
400c799d6bdSJohn Garry 	__le32 page_ctrl_0;
401c799d6bdSJohn Garry 	__le32 page_ctrl_1;
402c799d6bdSJohn Garry 	__le32 data_len;
403c799d6bdSJohn Garry 	__le32 data_off;
404c799d6bdSJohn Garry };
405c799d6bdSJohn Garry 
406c799d6bdSJohn Garry struct hisi_sas_command_table_smp {
407c799d6bdSJohn Garry 	u8 bytes[44];
408c799d6bdSJohn Garry };
409c799d6bdSJohn Garry 
410c799d6bdSJohn Garry struct hisi_sas_command_table_stp {
411c799d6bdSJohn Garry 	struct	host_to_dev_fis command_fis;
412c799d6bdSJohn Garry 	u8	dummy[12];
413c799d6bdSJohn Garry 	u8	atapi_cdb[ATAPI_CDB_LEN];
414c799d6bdSJohn Garry };
415c799d6bdSJohn Garry 
41665e8617fSMing Lin #define HISI_SAS_SGE_PAGE_CNT SG_CHUNK_SIZE
417c799d6bdSJohn Garry struct hisi_sas_sge_page {
418c799d6bdSJohn Garry 	struct hisi_sas_sge sge[HISI_SAS_SGE_PAGE_CNT];
419f557e32cSXiaofei Tan }  __aligned(16);
420c799d6bdSJohn Garry 
421c799d6bdSJohn Garry struct hisi_sas_command_table_ssp {
422c799d6bdSJohn Garry 	struct ssp_frame_hdr hdr;
423c799d6bdSJohn Garry 	union {
424c799d6bdSJohn Garry 		struct {
425c799d6bdSJohn Garry 			struct ssp_command_iu task;
426a14da7a2SXiang Chen 			u32 prot[7];
427c799d6bdSJohn Garry 		};
428c799d6bdSJohn Garry 		struct ssp_tmf_iu ssp_task;
429c799d6bdSJohn Garry 		struct xfer_rdy_iu xfer_rdy;
430c799d6bdSJohn Garry 		struct ssp_response_iu ssp_res;
431c799d6bdSJohn Garry 	} u;
432c799d6bdSJohn Garry };
433c799d6bdSJohn Garry 
434c799d6bdSJohn Garry union hisi_sas_command_table {
435c799d6bdSJohn Garry 	struct hisi_sas_command_table_ssp ssp;
436c799d6bdSJohn Garry 	struct hisi_sas_command_table_smp smp;
437c799d6bdSJohn Garry 	struct hisi_sas_command_table_stp stp;
438f557e32cSXiaofei Tan }  __aligned(16);
439f557e32cSXiaofei Tan 
440f557e32cSXiaofei Tan struct hisi_sas_status_buffer {
441f557e32cSXiaofei Tan 	struct hisi_sas_err_record err;
442f557e32cSXiaofei Tan 	u8	iu[1024];
443f557e32cSXiaofei Tan }  __aligned(16);
444f557e32cSXiaofei Tan 
445f557e32cSXiaofei Tan struct hisi_sas_slot_buf_table {
446f557e32cSXiaofei Tan 	struct hisi_sas_status_buffer status_buffer;
447f557e32cSXiaofei Tan 	union hisi_sas_command_table command_header;
448f557e32cSXiaofei Tan 	struct hisi_sas_sge_page sge_page;
449c799d6bdSJohn Garry };
4502e244f0fSJohn Garry 
451e21fe3a5SJohn Garry extern struct scsi_transport_template *hisi_sas_stt;
452a25d0d3dSXiang Chen extern void hisi_sas_stop_phys(struct hisi_hba *hisi_hba);
453e21fe3a5SJohn Garry extern int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost);
454e21fe3a5SJohn Garry extern void hisi_sas_free(struct hisi_hba *hisi_hba);
455468f4b8dSchenxiang extern u8 hisi_sas_get_ata_protocol(struct host_to_dev_fis *fis,
456468f4b8dSchenxiang 				int direction);
4572e244f0fSJohn Garry extern struct hisi_sas_port *to_hisi_sas_port(struct asd_sas_port *sas_port);
45875904077SXiang Chen extern void hisi_sas_sata_done(struct sas_task *task,
45975904077SXiang Chen 			    struct hisi_sas_slot *slot);
460318913c6SXiang Chen extern int hisi_sas_get_ncq_tag(struct sas_task *task, u32 *tag);
4610fa24c19SJohn Garry extern int hisi_sas_get_fw_info(struct hisi_hba *hisi_hba);
4629fb10b54SJohn Garry extern int hisi_sas_probe(struct platform_device *pdev,
4639fb10b54SJohn Garry 			  const struct hisi_sas_hw *ops);
4649fb10b54SJohn Garry extern int hisi_sas_remove(struct platform_device *pdev);
465c799d6bdSJohn Garry 
466235bfc7fSXiang Chen extern int hisi_sas_slave_configure(struct scsi_device *sdev);
467235bfc7fSXiang Chen extern int hisi_sas_scan_finished(struct Scsi_Host *shost, unsigned long time);
468235bfc7fSXiang Chen extern void hisi_sas_scan_start(struct Scsi_Host *shost);
469235bfc7fSXiang Chen extern struct device_attribute *host_attrs[];
470235bfc7fSXiang Chen extern int hisi_sas_host_reset(struct Scsi_Host *shost, int reset_type);
471184a4635SJohn Garry extern void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy);
47227a3f229SJohn Garry extern void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba,
47327a3f229SJohn Garry 				    struct sas_task *task,
47427a3f229SJohn Garry 				    struct hisi_sas_slot *slot);
47506ec0fb9SXiang Chen extern void hisi_sas_init_mem(struct hisi_hba *hisi_hba);
476b4241f0fSXiaofei Tan extern void hisi_sas_rst_work_handler(struct work_struct *work);
477e402acdbSXiaofei Tan extern void hisi_sas_sync_rst_work_handler(struct work_struct *work);
478571295f8SXiaofei Tan extern void hisi_sas_kill_tasklets(struct hisi_hba *hisi_hba);
479e537b62bSXiaofei Tan extern bool hisi_sas_notify_phy_event(struct hisi_sas_phy *phy,
480e537b62bSXiaofei Tan 				enum hisi_sas_phy_event event);
4814d0951eeSXiang Chen extern void hisi_sas_release_tasks(struct hisi_hba *hisi_hba);
482c2c1d9deSXiang Chen extern u8 hisi_sas_get_prog_phy_linkrate_mask(enum sas_linkrate max);
483e8899fadSJohn Garry #endif
484