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> 192ba5afb6SXiang Chen #include <linux/lcm.h> 20e8899fadSJohn Garry #include <linux/mfd/syscon.h> 21e8899fadSJohn Garry #include <linux/module.h> 22e8899fadSJohn Garry #include <linux/of_address.h> 2311b75249SJohn Garry #include <linux/pci.h> 24e8899fadSJohn Garry #include <linux/platform_device.h> 254d558c77SJohn Garry #include <linux/property.h> 26e8899fadSJohn Garry #include <linux/regmap.h> 276f2ff1a1SJohn Garry #include <scsi/sas_ata.h> 28e8899fadSJohn Garry #include <scsi/libsas.h> 29e8899fadSJohn Garry 307eb7869fSJohn Garry #define HISI_SAS_MAX_PHYS 9 316be6de18SJohn Garry #define HISI_SAS_MAX_QUEUES 32 326be6de18SJohn Garry #define HISI_SAS_QUEUE_SLOTS 512 333297ded1SXiang Chen #define HISI_SAS_MAX_ITCT_ENTRIES 1024 347eb7869fSJohn Garry #define HISI_SAS_MAX_DEVICES HISI_SAS_MAX_ITCT_ENTRIES 3506ec0fb9SXiang Chen #define HISI_SAS_RESET_BIT 0 36917d3bdaSXiaofei Tan #define HISI_SAS_REJECT_CMD_BIT 1 37*784b46b7SXiang Chen #define HISI_SAS_RESERVED_IPTT_CNT 96 387eb7869fSJohn Garry 39f557e32cSXiaofei Tan #define HISI_SAS_STATUS_BUF_SZ (sizeof(struct hisi_sas_status_buffer)) 40f557e32cSXiaofei Tan #define HISI_SAS_COMMAND_TABLE_SZ (sizeof(union hisi_sas_command_table)) 41f557e32cSXiaofei Tan 42f557e32cSXiaofei Tan #define hisi_sas_status_buf_addr(buf) \ 43f557e32cSXiaofei Tan (buf + offsetof(struct hisi_sas_slot_buf_table, status_buffer)) 44f557e32cSXiaofei Tan #define hisi_sas_status_buf_addr_mem(slot) hisi_sas_status_buf_addr(slot->buf) 45f557e32cSXiaofei Tan #define hisi_sas_status_buf_addr_dma(slot) \ 46f557e32cSXiaofei Tan hisi_sas_status_buf_addr(slot->buf_dma) 47f557e32cSXiaofei Tan 48f557e32cSXiaofei Tan #define hisi_sas_cmd_hdr_addr(buf) \ 49f557e32cSXiaofei Tan (buf + offsetof(struct hisi_sas_slot_buf_table, command_header)) 50f557e32cSXiaofei Tan #define hisi_sas_cmd_hdr_addr_mem(slot) hisi_sas_cmd_hdr_addr(slot->buf) 51f557e32cSXiaofei Tan #define hisi_sas_cmd_hdr_addr_dma(slot) hisi_sas_cmd_hdr_addr(slot->buf_dma) 52f557e32cSXiaofei Tan 53f557e32cSXiaofei Tan #define hisi_sas_sge_addr(buf) \ 54f557e32cSXiaofei Tan (buf + offsetof(struct hisi_sas_slot_buf_table, sge_page)) 55f557e32cSXiaofei Tan #define hisi_sas_sge_addr_mem(slot) hisi_sas_sge_addr(slot->buf) 56f557e32cSXiaofei Tan #define hisi_sas_sge_addr_dma(slot) hisi_sas_sge_addr(slot->buf_dma) 576be6de18SJohn Garry 5842e7a693SJohn Garry #define HISI_SAS_MAX_SSP_RESP_SZ (sizeof(struct ssp_frame_hdr) + 1024) 5966ee999bSJohn Garry #define HISI_SAS_MAX_SMP_RESP_SZ 1028 606f2ff1a1SJohn Garry #define HISI_SAS_MAX_STP_RESP_SZ 28 6142e7a693SJohn Garry 6298bf39fcSJohn Garry #define DEV_IS_EXPANDER(type) \ 6398bf39fcSJohn Garry ((type == SAS_EDGE_EXPANDER_DEVICE) || \ 6498bf39fcSJohn Garry (type == SAS_FANOUT_EXPANDER_DEVICE)) 6598bf39fcSJohn Garry 666c7bb8a1SXiang Chen #define HISI_SAS_SATA_PROTOCOL_NONDATA 0x1 676c7bb8a1SXiang Chen #define HISI_SAS_SATA_PROTOCOL_PIO 0x2 686c7bb8a1SXiang Chen #define HISI_SAS_SATA_PROTOCOL_DMA 0x4 696c7bb8a1SXiang Chen #define HISI_SAS_SATA_PROTOCOL_FPDMA 0x8 706c7bb8a1SXiang Chen #define HISI_SAS_SATA_PROTOCOL_ATAPI 0x10 716c7bb8a1SXiang Chen 72abda97c2SJohn Garry struct hisi_hba; 73af740dbeSJohn Garry 7407d78592SJohn Garry enum { 7507d78592SJohn Garry PORT_TYPE_SAS = (1U << 1), 7607d78592SJohn Garry PORT_TYPE_SATA = (1U << 0), 7707d78592SJohn Garry }; 7807d78592SJohn Garry 79af740dbeSJohn Garry enum dev_status { 80af740dbeSJohn Garry HISI_SAS_DEV_NORMAL, 81af740dbeSJohn Garry HISI_SAS_DEV_EH, 82af740dbeSJohn Garry }; 83abda97c2SJohn Garry 84441c2740SJohn Garry enum { 85441c2740SJohn Garry HISI_SAS_INT_ABT_CMD = 0, 86441c2740SJohn Garry HISI_SAS_INT_ABT_DEV = 1, 87441c2740SJohn Garry }; 88441c2740SJohn Garry 89abda97c2SJohn Garry enum hisi_sas_dev_type { 90abda97c2SJohn Garry HISI_SAS_DEV_TYPE_STP = 0, 91abda97c2SJohn Garry HISI_SAS_DEV_TYPE_SSP, 92abda97c2SJohn Garry HISI_SAS_DEV_TYPE_SATA, 93abda97c2SJohn Garry }; 94abda97c2SJohn Garry 952b383351SJohn Garry struct hisi_sas_hw_error { 962b383351SJohn Garry u32 irq_msk; 972b383351SJohn Garry u32 msk; 982b383351SJohn Garry int shift; 992b383351SJohn Garry const char *msg; 1002b383351SJohn Garry int reg; 101729428caSShiju Jose const struct hisi_sas_hw_error *sub; 1022b383351SJohn Garry }; 1032b383351SJohn Garry 104e402acdbSXiaofei Tan struct hisi_sas_rst { 105e402acdbSXiaofei Tan struct hisi_hba *hisi_hba; 106e402acdbSXiaofei Tan struct completion *completion; 107e402acdbSXiaofei Tan struct work_struct work; 108e402acdbSXiaofei Tan bool done; 109e402acdbSXiaofei Tan }; 110e402acdbSXiaofei Tan 111e402acdbSXiaofei Tan #define HISI_SAS_RST_WORK_INIT(r, c) \ 112e402acdbSXiaofei Tan { .hisi_hba = hisi_hba, \ 113e402acdbSXiaofei Tan .completion = &c, \ 114e402acdbSXiaofei Tan .work = __WORK_INITIALIZER(r.work, \ 115e402acdbSXiaofei Tan hisi_sas_sync_rst_work_handler), \ 116e402acdbSXiaofei Tan .done = false, \ 117e402acdbSXiaofei Tan } 118e402acdbSXiaofei Tan 119e402acdbSXiaofei Tan #define HISI_SAS_DECLARE_RST_WORK_ON_STACK(r) \ 120e402acdbSXiaofei Tan DECLARE_COMPLETION_ONSTACK(c); \ 121e402acdbSXiaofei Tan DECLARE_WORK(w, hisi_sas_sync_rst_work_handler); \ 122e402acdbSXiaofei Tan struct hisi_sas_rst r = HISI_SAS_RST_WORK_INIT(r, c) 123e402acdbSXiaofei Tan 124e402acdbSXiaofei Tan enum hisi_sas_bit_err_type { 125e402acdbSXiaofei Tan HISI_SAS_ERR_SINGLE_BIT_ECC = 0x0, 126e402acdbSXiaofei Tan HISI_SAS_ERR_MULTI_BIT_ECC = 0x1, 127e402acdbSXiaofei Tan }; 128e402acdbSXiaofei Tan 129e537b62bSXiaofei Tan enum hisi_sas_phy_event { 130e537b62bSXiaofei Tan HISI_PHYE_PHY_UP = 0U, 131057c3d1fSXiaofei Tan HISI_PHYE_LINK_RESET, 132e537b62bSXiaofei Tan HISI_PHYES_NUM, 133e537b62bSXiaofei Tan }; 134e537b62bSXiaofei Tan 1357eb7869fSJohn Garry struct hisi_sas_phy { 136e537b62bSXiaofei Tan struct work_struct works[HISI_PHYES_NUM]; 137976867e6SJohn Garry struct hisi_hba *hisi_hba; 138976867e6SJohn Garry struct hisi_sas_port *port; 1397eb7869fSJohn Garry struct asd_sas_phy sas_phy; 140976867e6SJohn Garry struct sas_identify identify; 1413e1fb1b8SXiang Chen struct completion *reset_completion; 1423e1fb1b8SXiang Chen spinlock_t lock; 143976867e6SJohn Garry u64 port_id; /* from hw */ 144976867e6SJohn Garry u64 frame_rcvd_size; 145976867e6SJohn Garry u8 frame_rcvd[32]; 146976867e6SJohn Garry u8 phy_attached; 1473e1fb1b8SXiang Chen u8 in_reset; 1483e1fb1b8SXiang Chen u8 reserved[2]; 149d0ef10c9SJohn Garry u32 phy_type; 150976867e6SJohn Garry enum sas_linkrate minimum_linkrate; 151976867e6SJohn Garry enum sas_linkrate maximum_linkrate; 1527eb7869fSJohn Garry }; 1537eb7869fSJohn Garry 1547eb7869fSJohn Garry struct hisi_sas_port { 1557eb7869fSJohn Garry struct asd_sas_port sas_port; 156976867e6SJohn Garry u8 port_attached; 157976867e6SJohn Garry u8 id; /* from hw */ 1587eb7869fSJohn Garry }; 1597eb7869fSJohn Garry 1609101a079SJohn Garry struct hisi_sas_cq { 1619101a079SJohn Garry struct hisi_hba *hisi_hba; 162d177c408SJohn Garry struct tasklet_struct tasklet; 163e6c346f3SJohn Garry int rd_point; 1649101a079SJohn Garry int id; 1659101a079SJohn Garry }; 1669101a079SJohn Garry 1674fde02adSJohn Garry struct hisi_sas_dq { 1684fde02adSJohn Garry struct hisi_hba *hisi_hba; 169fa222db0SXiang Chen struct list_head list; 170b1a49412SXiang Chen spinlock_t lock; 1714fde02adSJohn Garry int wr_point; 1724fde02adSJohn Garry int id; 1734fde02adSJohn Garry }; 1744fde02adSJohn Garry 175af740dbeSJohn Garry struct hisi_sas_device { 176abda97c2SJohn Garry struct hisi_hba *hisi_hba; 177abda97c2SJohn Garry struct domain_device *sas_device; 178640acc9aSXiang Chen struct completion *completion; 179b1a49412SXiang Chen struct hisi_sas_dq *dq; 180405314dfSJohn Garry struct list_head list; 181ad604832SJohn Garry enum sas_device_type dev_type; 182ad604832SJohn Garry int device_id; 18332ccba52SXiaofei Tan int sata_idx; 184ad604832SJohn Garry u8 dev_status; 185af740dbeSJohn Garry }; 186af740dbeSJohn Garry 18778bd2b4fSXiaofei Tan struct hisi_sas_tmf_task { 188b09fcd09SXiaofei Tan int force_phy; 189b09fcd09SXiaofei Tan int phy_id; 19078bd2b4fSXiaofei Tan u8 tmf; 19178bd2b4fSXiaofei Tan u16 tag_of_task_to_be_managed; 19278bd2b4fSXiaofei Tan }; 19378bd2b4fSXiaofei Tan 1946be6de18SJohn Garry struct hisi_sas_slot { 19542e7a693SJohn Garry struct list_head entry; 196fa222db0SXiang Chen struct list_head delivery; 19742e7a693SJohn Garry struct sas_task *task; 19842e7a693SJohn Garry struct hisi_sas_port *port; 19942e7a693SJohn Garry u64 n_elem; 20042e7a693SJohn Garry int dlvry_queue; 20142e7a693SJohn Garry int dlvry_queue_slot; 20227a3f229SJohn Garry int cmplt_queue; 20327a3f229SJohn Garry int cmplt_queue_slot; 204cac9b2a2SJohn Garry int abort; 205fa222db0SXiang Chen int ready; 20642e7a693SJohn Garry void *cmd_hdr; 20742e7a693SJohn Garry dma_addr_t cmd_hdr_dma; 2080844a3ffSJohn Garry struct timer_list internal_abort_timer; 209cd938e53SXiang Chen bool is_internal; 21078bd2b4fSXiaofei Tan struct hisi_sas_tmf_task *tmf; 2112ba5afb6SXiang Chen /* Do not reorder/change members after here */ 2122ba5afb6SXiang Chen void *buf; 2132ba5afb6SXiang Chen dma_addr_t buf_dma; 2142ba5afb6SXiang Chen int idx; 2156be6de18SJohn Garry }; 2166be6de18SJohn Garry 2177eb7869fSJohn Garry struct hisi_sas_hw { 2188ff1d571SJohn Garry int (*hw_init)(struct hisi_hba *hisi_hba); 219abda97c2SJohn Garry void (*setup_itct)(struct hisi_hba *hisi_hba, 220abda97c2SJohn Garry struct hisi_sas_device *device); 221*784b46b7SXiang Chen int (*slot_index_alloc)(struct hisi_hba *hisi_hba, 222685b6d6eSJohn Garry struct domain_device *device); 223685b6d6eSJohn Garry struct hisi_sas_device *(*alloc_dev)(struct domain_device *device); 22466139921SJohn Garry void (*sl_notify)(struct hisi_hba *hisi_hba, int phy_no); 225b1a49412SXiang Chen int (*get_free_slot)(struct hisi_hba *hisi_hba, struct hisi_sas_dq *dq); 226b1a49412SXiang Chen void (*start_delivery)(struct hisi_sas_dq *dq); 227a2b3820bSXiang Chen void (*prep_ssp)(struct hisi_hba *hisi_hba, 22878bd2b4fSXiaofei Tan struct hisi_sas_slot *slot); 229a2b3820bSXiang Chen void (*prep_smp)(struct hisi_hba *hisi_hba, 23066ee999bSJohn Garry struct hisi_sas_slot *slot); 231a2b3820bSXiang Chen void (*prep_stp)(struct hisi_hba *hisi_hba, 2326f2ff1a1SJohn Garry struct hisi_sas_slot *slot); 233a2b3820bSXiang Chen void (*prep_abort)(struct hisi_hba *hisi_hba, 234441c2740SJohn Garry struct hisi_sas_slot *slot, 235441c2740SJohn Garry int device_id, int abort_flag, int tag_to_abort); 23627a3f229SJohn Garry int (*slot_complete)(struct hisi_hba *hisi_hba, 237405314dfSJohn Garry struct hisi_sas_slot *slot); 238396b8044SJohn Garry void (*phys_init)(struct hisi_hba *hisi_hba); 2391eb8eeacSXiang Chen void (*phy_start)(struct hisi_hba *hisi_hba, int phy_no); 240e4189d53SJohn Garry void (*phy_disable)(struct hisi_hba *hisi_hba, int phy_no); 241e4189d53SJohn Garry void (*phy_hard_reset)(struct hisi_hba *hisi_hba, int phy_no); 242c52108c6SXiaofei Tan void (*get_events)(struct hisi_hba *hisi_hba, int phy_no); 2432ae75787SXiang Chen void (*phy_set_linkrate)(struct hisi_hba *hisi_hba, int phy_no, 2442ae75787SXiang Chen struct sas_phy_linkrates *linkrates); 2452ae75787SXiang Chen enum sas_linkrate (*phy_get_max_linkrate)(void); 2460258141aSXiaofei Tan void (*clear_itct)(struct hisi_hba *hisi_hba, 24727a3f229SJohn Garry struct hisi_sas_device *dev); 2480258141aSXiaofei Tan void (*free_device)(struct hisi_sas_device *sas_dev); 249184a4635SJohn Garry int (*get_wideport_bitmap)(struct hisi_hba *hisi_hba, int port_id); 250d30ff263SXiang Chen void (*dereg_device)(struct hisi_hba *hisi_hba, 251d30ff263SXiang Chen struct domain_device *device); 25206ec0fb9SXiang Chen int (*soft_reset)(struct hisi_hba *hisi_hba); 253917d3bdaSXiaofei Tan u32 (*get_phys_state)(struct hisi_hba *hisi_hba); 2546379c560SXiaofei Tan int (*write_gpio)(struct hisi_hba *hisi_hba, u8 reg_type, 2556379c560SXiaofei Tan u8 reg_index, u8 reg_count, u8 *write_data); 256a865ae14SXiaofei Tan void (*wait_cmds_complete_timeout)(struct hisi_hba *hisi_hba, 257a865ae14SXiaofei Tan int delay_ms, int timeout_ms); 258a8d547bdSJohn Garry int max_command_entries; 2596be6de18SJohn Garry int complete_hdr_size; 260235bfc7fSXiang Chen struct scsi_host_template *sht; 2617eb7869fSJohn Garry }; 2627eb7869fSJohn Garry 2637eb7869fSJohn Garry struct hisi_hba { 2647eb7869fSJohn Garry /* This must be the first element, used by SHOST_TO_SAS_HA */ 2657eb7869fSJohn Garry struct sas_ha_struct *p; 2667eb7869fSJohn Garry 26711b75249SJohn Garry struct platform_device *platform_dev; 26811b75249SJohn Garry struct pci_dev *pci_dev; 26911b75249SJohn Garry struct device *dev; 27011b75249SJohn Garry 271e26b2f40SJohn Garry void __iomem *regs; 2726379c560SXiaofei Tan void __iomem *sgpio_regs; 273e26b2f40SJohn Garry struct regmap *ctrl; 274e26b2f40SJohn Garry u32 ctrl_reset_reg; 275e26b2f40SJohn Garry u32 ctrl_reset_sts_reg; 276e26b2f40SJohn Garry u32 ctrl_clock_ena_reg; 2773bc45af8SJohn Garry u32 refclk_frequency_mhz; 2787eb7869fSJohn Garry u8 sas_addr[SAS_ADDR_SIZE]; 2797eb7869fSJohn Garry 2807eb7869fSJohn Garry int n_phy; 281fa42d80dSJohn Garry spinlock_t lock; 282d2fc401eSXiaofei Tan struct semaphore sem; 2837eb7869fSJohn Garry 284fa42d80dSJohn Garry struct timer_list timer; 2857e9080e1SJohn Garry struct workqueue_struct *wq; 286257efd1fSJohn Garry 287257efd1fSJohn Garry int slot_index_count; 288fa3be0f2SXiang Chen int last_slot_index; 2891b865185SXiang Chen int last_dev_id; 290257efd1fSJohn Garry unsigned long *slot_index_tags; 291c7b9d369SXiaofei Tan unsigned long reject_stp_links_msk; 292257efd1fSJohn Garry 2937eb7869fSJohn Garry /* SCSI/SAS glue */ 2947eb7869fSJohn Garry struct sas_ha_struct sha; 2957eb7869fSJohn Garry struct Scsi_Host *shost; 2969101a079SJohn Garry 2979101a079SJohn Garry struct hisi_sas_cq cq[HISI_SAS_MAX_QUEUES]; 2984fde02adSJohn Garry struct hisi_sas_dq dq[HISI_SAS_MAX_QUEUES]; 2997eb7869fSJohn Garry struct hisi_sas_phy phy[HISI_SAS_MAX_PHYS]; 3007eb7869fSJohn Garry struct hisi_sas_port port[HISI_SAS_MAX_PHYS]; 301e26b2f40SJohn Garry 302e26b2f40SJohn Garry int queue_count; 3036be6de18SJohn Garry 304af740dbeSJohn Garry struct hisi_sas_device devices[HISI_SAS_MAX_DEVICES]; 3056be6de18SJohn Garry struct hisi_sas_cmd_hdr *cmd_hdr[HISI_SAS_MAX_QUEUES]; 3066be6de18SJohn Garry dma_addr_t cmd_hdr_dma[HISI_SAS_MAX_QUEUES]; 3076be6de18SJohn Garry void *complete_hdr[HISI_SAS_MAX_QUEUES]; 3086be6de18SJohn Garry dma_addr_t complete_hdr_dma[HISI_SAS_MAX_QUEUES]; 3096be6de18SJohn Garry struct hisi_sas_initial_fis *initial_fis; 3106be6de18SJohn Garry dma_addr_t initial_fis_dma; 3116be6de18SJohn Garry struct hisi_sas_itct *itct; 3126be6de18SJohn Garry dma_addr_t itct_dma; 3136be6de18SJohn Garry struct hisi_sas_iost *iost; 3146be6de18SJohn Garry dma_addr_t iost_dma; 3156be6de18SJohn Garry struct hisi_sas_breakpoint *breakpoint; 3166be6de18SJohn Garry dma_addr_t breakpoint_dma; 3176be6de18SJohn Garry struct hisi_sas_breakpoint *sata_breakpoint; 3186be6de18SJohn Garry dma_addr_t sata_breakpoint_dma; 3196be6de18SJohn Garry struct hisi_sas_slot *slot_info; 32006ec0fb9SXiang Chen unsigned long flags; 3217eb7869fSJohn Garry const struct hisi_sas_hw *hw; /* Low level hw interface */ 32232ccba52SXiaofei Tan unsigned long sata_dev_bitmap[BITS_TO_LONGS(HISI_SAS_MAX_DEVICES)]; 32306ec0fb9SXiang Chen struct work_struct rst_work; 3244522204aSXiaofei Tan u32 phy_state; 3257eb7869fSJohn Garry }; 3267eb7869fSJohn Garry 327c799d6bdSJohn Garry /* Generic HW DMA host memory structures */ 328c799d6bdSJohn Garry /* Delivery queue header */ 329c799d6bdSJohn Garry struct hisi_sas_cmd_hdr { 330c799d6bdSJohn Garry /* dw0 */ 331c799d6bdSJohn Garry __le32 dw0; 332c799d6bdSJohn Garry 333c799d6bdSJohn Garry /* dw1 */ 334c799d6bdSJohn Garry __le32 dw1; 335c799d6bdSJohn Garry 336c799d6bdSJohn Garry /* dw2 */ 337c799d6bdSJohn Garry __le32 dw2; 338c799d6bdSJohn Garry 339c799d6bdSJohn Garry /* dw3 */ 340c799d6bdSJohn Garry __le32 transfer_tags; 341c799d6bdSJohn Garry 342c799d6bdSJohn Garry /* dw4 */ 343c799d6bdSJohn Garry __le32 data_transfer_len; 344c799d6bdSJohn Garry 345c799d6bdSJohn Garry /* dw5 */ 346c799d6bdSJohn Garry __le32 first_burst_num; 347c799d6bdSJohn Garry 348c799d6bdSJohn Garry /* dw6 */ 349c799d6bdSJohn Garry __le32 sg_len; 350c799d6bdSJohn Garry 351c799d6bdSJohn Garry /* dw7 */ 352c799d6bdSJohn Garry __le32 dw7; 353c799d6bdSJohn Garry 354c799d6bdSJohn Garry /* dw8-9 */ 355c799d6bdSJohn Garry __le64 cmd_table_addr; 356c799d6bdSJohn Garry 357c799d6bdSJohn Garry /* dw10-11 */ 358c799d6bdSJohn Garry __le64 sts_buffer_addr; 359c799d6bdSJohn Garry 360c799d6bdSJohn Garry /* dw12-13 */ 361c799d6bdSJohn Garry __le64 prd_table_addr; 362c799d6bdSJohn Garry 363c799d6bdSJohn Garry /* dw14-15 */ 364c799d6bdSJohn Garry __le64 dif_prd_table_addr; 365c799d6bdSJohn Garry }; 366c799d6bdSJohn Garry 367c799d6bdSJohn Garry struct hisi_sas_itct { 368c799d6bdSJohn Garry __le64 qw0; 369c799d6bdSJohn Garry __le64 sas_addr; 370c799d6bdSJohn Garry __le64 qw2; 371c799d6bdSJohn Garry __le64 qw3; 372281e3bf6SJohn Garry __le64 qw4_15[12]; 373c799d6bdSJohn Garry }; 374c799d6bdSJohn Garry 375c799d6bdSJohn Garry struct hisi_sas_iost { 376c799d6bdSJohn Garry __le64 qw0; 377c799d6bdSJohn Garry __le64 qw1; 378c799d6bdSJohn Garry __le64 qw2; 379c799d6bdSJohn Garry __le64 qw3; 380c799d6bdSJohn Garry }; 381c799d6bdSJohn Garry 382c799d6bdSJohn Garry struct hisi_sas_err_record { 3838d1eee7dSJohn Garry u32 data[4]; 384c799d6bdSJohn Garry }; 385c799d6bdSJohn Garry 386c799d6bdSJohn Garry struct hisi_sas_initial_fis { 387c799d6bdSJohn Garry struct hisi_sas_err_record err_record; 388c799d6bdSJohn Garry struct dev_to_host_fis fis; 389c799d6bdSJohn Garry u32 rsvd[3]; 390c799d6bdSJohn Garry }; 391c799d6bdSJohn Garry 392c799d6bdSJohn Garry struct hisi_sas_breakpoint { 3933297ded1SXiang Chen u8 data[128]; 3943297ded1SXiang Chen }; 3953297ded1SXiang Chen 3963297ded1SXiang Chen struct hisi_sas_sata_breakpoint { 3973297ded1SXiang Chen struct hisi_sas_breakpoint tag[32]; 398c799d6bdSJohn Garry }; 399c799d6bdSJohn Garry 400c799d6bdSJohn Garry struct hisi_sas_sge { 401c799d6bdSJohn Garry __le64 addr; 402c799d6bdSJohn Garry __le32 page_ctrl_0; 403c799d6bdSJohn Garry __le32 page_ctrl_1; 404c799d6bdSJohn Garry __le32 data_len; 405c799d6bdSJohn Garry __le32 data_off; 406c799d6bdSJohn Garry }; 407c799d6bdSJohn Garry 408c799d6bdSJohn Garry struct hisi_sas_command_table_smp { 409c799d6bdSJohn Garry u8 bytes[44]; 410c799d6bdSJohn Garry }; 411c799d6bdSJohn Garry 412c799d6bdSJohn Garry struct hisi_sas_command_table_stp { 413c799d6bdSJohn Garry struct host_to_dev_fis command_fis; 414c799d6bdSJohn Garry u8 dummy[12]; 415c799d6bdSJohn Garry u8 atapi_cdb[ATAPI_CDB_LEN]; 416c799d6bdSJohn Garry }; 417c799d6bdSJohn Garry 41865e8617fSMing Lin #define HISI_SAS_SGE_PAGE_CNT SG_CHUNK_SIZE 419c799d6bdSJohn Garry struct hisi_sas_sge_page { 420c799d6bdSJohn Garry struct hisi_sas_sge sge[HISI_SAS_SGE_PAGE_CNT]; 421f557e32cSXiaofei Tan } __aligned(16); 422c799d6bdSJohn Garry 423c799d6bdSJohn Garry struct hisi_sas_command_table_ssp { 424c799d6bdSJohn Garry struct ssp_frame_hdr hdr; 425c799d6bdSJohn Garry union { 426c799d6bdSJohn Garry struct { 427c799d6bdSJohn Garry struct ssp_command_iu task; 428a14da7a2SXiang Chen u32 prot[7]; 429c799d6bdSJohn Garry }; 430c799d6bdSJohn Garry struct ssp_tmf_iu ssp_task; 431c799d6bdSJohn Garry struct xfer_rdy_iu xfer_rdy; 432c799d6bdSJohn Garry struct ssp_response_iu ssp_res; 433c799d6bdSJohn Garry } u; 434c799d6bdSJohn Garry }; 435c799d6bdSJohn Garry 436c799d6bdSJohn Garry union hisi_sas_command_table { 437c799d6bdSJohn Garry struct hisi_sas_command_table_ssp ssp; 438c799d6bdSJohn Garry struct hisi_sas_command_table_smp smp; 439c799d6bdSJohn Garry struct hisi_sas_command_table_stp stp; 440f557e32cSXiaofei Tan } __aligned(16); 441f557e32cSXiaofei Tan 442f557e32cSXiaofei Tan struct hisi_sas_status_buffer { 443f557e32cSXiaofei Tan struct hisi_sas_err_record err; 444f557e32cSXiaofei Tan u8 iu[1024]; 445f557e32cSXiaofei Tan } __aligned(16); 446f557e32cSXiaofei Tan 447f557e32cSXiaofei Tan struct hisi_sas_slot_buf_table { 448f557e32cSXiaofei Tan struct hisi_sas_status_buffer status_buffer; 449f557e32cSXiaofei Tan union hisi_sas_command_table command_header; 450f557e32cSXiaofei Tan struct hisi_sas_sge_page sge_page; 451c799d6bdSJohn Garry }; 4522e244f0fSJohn Garry 453e21fe3a5SJohn Garry extern struct scsi_transport_template *hisi_sas_stt; 454a25d0d3dSXiang Chen extern void hisi_sas_stop_phys(struct hisi_hba *hisi_hba); 455e21fe3a5SJohn Garry extern int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost); 456e21fe3a5SJohn Garry extern void hisi_sas_free(struct hisi_hba *hisi_hba); 457468f4b8dSchenxiang extern u8 hisi_sas_get_ata_protocol(struct host_to_dev_fis *fis, 458468f4b8dSchenxiang int direction); 4592e244f0fSJohn Garry extern struct hisi_sas_port *to_hisi_sas_port(struct asd_sas_port *sas_port); 46075904077SXiang Chen extern void hisi_sas_sata_done(struct sas_task *task, 46175904077SXiang Chen struct hisi_sas_slot *slot); 462318913c6SXiang Chen extern int hisi_sas_get_ncq_tag(struct sas_task *task, u32 *tag); 4630fa24c19SJohn Garry extern int hisi_sas_get_fw_info(struct hisi_hba *hisi_hba); 4649fb10b54SJohn Garry extern int hisi_sas_probe(struct platform_device *pdev, 4659fb10b54SJohn Garry const struct hisi_sas_hw *ops); 4669fb10b54SJohn Garry extern int hisi_sas_remove(struct platform_device *pdev); 467c799d6bdSJohn Garry 468235bfc7fSXiang Chen extern int hisi_sas_slave_configure(struct scsi_device *sdev); 469235bfc7fSXiang Chen extern int hisi_sas_scan_finished(struct Scsi_Host *shost, unsigned long time); 470235bfc7fSXiang Chen extern void hisi_sas_scan_start(struct Scsi_Host *shost); 471235bfc7fSXiang Chen extern struct device_attribute *host_attrs[]; 472235bfc7fSXiang Chen extern int hisi_sas_host_reset(struct Scsi_Host *shost, int reset_type); 473184a4635SJohn Garry extern void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy); 47427a3f229SJohn Garry extern void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, 47527a3f229SJohn Garry struct sas_task *task, 47627a3f229SJohn Garry struct hisi_sas_slot *slot); 47706ec0fb9SXiang Chen extern void hisi_sas_init_mem(struct hisi_hba *hisi_hba); 478b4241f0fSXiaofei Tan extern void hisi_sas_rst_work_handler(struct work_struct *work); 479e402acdbSXiaofei Tan extern void hisi_sas_sync_rst_work_handler(struct work_struct *work); 480571295f8SXiaofei Tan extern void hisi_sas_kill_tasklets(struct hisi_hba *hisi_hba); 481e537b62bSXiaofei Tan extern bool hisi_sas_notify_phy_event(struct hisi_sas_phy *phy, 482e537b62bSXiaofei Tan enum hisi_sas_phy_event event); 4834d0951eeSXiang Chen extern void hisi_sas_release_tasks(struct hisi_hba *hisi_hba); 484c2c1d9deSXiang Chen extern u8 hisi_sas_get_prog_phy_linkrate_mask(enum sas_linkrate max); 4854522204aSXiaofei Tan extern void hisi_sas_controller_reset_prepare(struct hisi_hba *hisi_hba); 4864522204aSXiaofei Tan extern void hisi_sas_controller_reset_done(struct hisi_hba *hisi_hba); 487e8899fadSJohn Garry #endif 488