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