18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Marvell 88SE64xx/88SE94xx main function head file 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright 2007 Red Hat, Inc. 68c2ecf20Sopenharmony_ci * Copyright 2008 Marvell. <kewei@marvell.com> 78c2ecf20Sopenharmony_ci * Copyright 2009-2011 Marvell. <yuxiangl@marvell.com> 88c2ecf20Sopenharmony_ci*/ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#ifndef _MV_SAS_H_ 118c2ecf20Sopenharmony_ci#define _MV_SAS_H_ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <linux/kernel.h> 148c2ecf20Sopenharmony_ci#include <linux/module.h> 158c2ecf20Sopenharmony_ci#include <linux/spinlock.h> 168c2ecf20Sopenharmony_ci#include <linux/delay.h> 178c2ecf20Sopenharmony_ci#include <linux/types.h> 188c2ecf20Sopenharmony_ci#include <linux/ctype.h> 198c2ecf20Sopenharmony_ci#include <linux/dma-mapping.h> 208c2ecf20Sopenharmony_ci#include <linux/pci.h> 218c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 228c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 238c2ecf20Sopenharmony_ci#include <linux/irq.h> 248c2ecf20Sopenharmony_ci#include <linux/slab.h> 258c2ecf20Sopenharmony_ci#include <linux/vmalloc.h> 268c2ecf20Sopenharmony_ci#include <asm/unaligned.h> 278c2ecf20Sopenharmony_ci#include <scsi/libsas.h> 288c2ecf20Sopenharmony_ci#include <scsi/scsi.h> 298c2ecf20Sopenharmony_ci#include <scsi/scsi_tcq.h> 308c2ecf20Sopenharmony_ci#include <scsi/sas_ata.h> 318c2ecf20Sopenharmony_ci#include "mv_defs.h" 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci#define DRV_NAME "mvsas" 348c2ecf20Sopenharmony_ci#define DRV_VERSION "0.8.16" 358c2ecf20Sopenharmony_ci#define MVS_ID_NOT_MAPPED 0x7f 368c2ecf20Sopenharmony_ci#define WIDE_PORT_MAX_PHY 4 378c2ecf20Sopenharmony_ci#define mv_printk(fmt, arg ...) \ 388c2ecf20Sopenharmony_ci printk(KERN_DEBUG"%s %d:" fmt, __FILE__, __LINE__, ## arg) 398c2ecf20Sopenharmony_ci#ifdef MV_DEBUG 408c2ecf20Sopenharmony_ci#define mv_dprintk(format, arg...) \ 418c2ecf20Sopenharmony_ci printk(KERN_DEBUG"%s %d:" format, __FILE__, __LINE__, ## arg) 428c2ecf20Sopenharmony_ci#else 438c2ecf20Sopenharmony_ci#define mv_dprintk(format, arg...) 448c2ecf20Sopenharmony_ci#endif 458c2ecf20Sopenharmony_ci#define MV_MAX_U32 0xffffffff 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ciextern int interrupt_coalescing; 488c2ecf20Sopenharmony_ciextern struct mvs_tgt_initiator mvs_tgt; 498c2ecf20Sopenharmony_ciextern struct mvs_info *tgt_mvi; 508c2ecf20Sopenharmony_ciextern const struct mvs_dispatch mvs_64xx_dispatch; 518c2ecf20Sopenharmony_ciextern const struct mvs_dispatch mvs_94xx_dispatch; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci#define bit(n) ((u64)1 << n) 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci#define for_each_phy(__lseq_mask, __mc, __lseq) \ 568c2ecf20Sopenharmony_ci for ((__mc) = (__lseq_mask), (__lseq) = 0; \ 578c2ecf20Sopenharmony_ci (__mc) != 0 ; \ 588c2ecf20Sopenharmony_ci (++__lseq), (__mc) >>= 1) 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci#define MVS_PHY_ID (1U << sas_phy->id) 618c2ecf20Sopenharmony_ci#define MV_INIT_DELAYED_WORK(w, f, d) INIT_DELAYED_WORK(w, f) 628c2ecf20Sopenharmony_ci#define UNASSOC_D2H_FIS(id) \ 638c2ecf20Sopenharmony_ci ((void *) mvi->rx_fis + 0x100 * id) 648c2ecf20Sopenharmony_ci#define SATA_RECEIVED_FIS_LIST(reg_set) \ 658c2ecf20Sopenharmony_ci ((void *) mvi->rx_fis + mvi->chip->fis_offs + 0x100 * reg_set) 668c2ecf20Sopenharmony_ci#define SATA_RECEIVED_SDB_FIS(reg_set) \ 678c2ecf20Sopenharmony_ci (SATA_RECEIVED_FIS_LIST(reg_set) + 0x58) 688c2ecf20Sopenharmony_ci#define SATA_RECEIVED_D2H_FIS(reg_set) \ 698c2ecf20Sopenharmony_ci (SATA_RECEIVED_FIS_LIST(reg_set) + 0x40) 708c2ecf20Sopenharmony_ci#define SATA_RECEIVED_PIO_FIS(reg_set) \ 718c2ecf20Sopenharmony_ci (SATA_RECEIVED_FIS_LIST(reg_set) + 0x20) 728c2ecf20Sopenharmony_ci#define SATA_RECEIVED_DMA_FIS(reg_set) \ 738c2ecf20Sopenharmony_ci (SATA_RECEIVED_FIS_LIST(reg_set) + 0x00) 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_cienum dev_status { 768c2ecf20Sopenharmony_ci MVS_DEV_NORMAL = 0x0, 778c2ecf20Sopenharmony_ci MVS_DEV_EH = 0x1, 788c2ecf20Sopenharmony_ci}; 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_cienum dev_reset { 818c2ecf20Sopenharmony_ci MVS_SOFT_RESET = 0, 828c2ecf20Sopenharmony_ci MVS_HARD_RESET = 1, 838c2ecf20Sopenharmony_ci MVS_PHY_TUNE = 2, 848c2ecf20Sopenharmony_ci}; 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_cistruct mvs_info; 878c2ecf20Sopenharmony_cistruct mvs_prv_info; 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_cistruct mvs_dispatch { 908c2ecf20Sopenharmony_ci char *name; 918c2ecf20Sopenharmony_ci int (*chip_init)(struct mvs_info *mvi); 928c2ecf20Sopenharmony_ci int (*spi_init)(struct mvs_info *mvi); 938c2ecf20Sopenharmony_ci int (*chip_ioremap)(struct mvs_info *mvi); 948c2ecf20Sopenharmony_ci void (*chip_iounmap)(struct mvs_info *mvi); 958c2ecf20Sopenharmony_ci irqreturn_t (*isr)(struct mvs_info *mvi, int irq, u32 stat); 968c2ecf20Sopenharmony_ci u32 (*isr_status)(struct mvs_info *mvi, int irq); 978c2ecf20Sopenharmony_ci void (*interrupt_enable)(struct mvs_info *mvi); 988c2ecf20Sopenharmony_ci void (*interrupt_disable)(struct mvs_info *mvi); 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci u32 (*read_phy_ctl)(struct mvs_info *mvi, u32 port); 1018c2ecf20Sopenharmony_ci void (*write_phy_ctl)(struct mvs_info *mvi, u32 port, u32 val); 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci u32 (*read_port_cfg_data)(struct mvs_info *mvi, u32 port); 1048c2ecf20Sopenharmony_ci void (*write_port_cfg_data)(struct mvs_info *mvi, u32 port, u32 val); 1058c2ecf20Sopenharmony_ci void (*write_port_cfg_addr)(struct mvs_info *mvi, u32 port, u32 addr); 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci u32 (*read_port_vsr_data)(struct mvs_info *mvi, u32 port); 1088c2ecf20Sopenharmony_ci void (*write_port_vsr_data)(struct mvs_info *mvi, u32 port, u32 val); 1098c2ecf20Sopenharmony_ci void (*write_port_vsr_addr)(struct mvs_info *mvi, u32 port, u32 addr); 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci u32 (*read_port_irq_stat)(struct mvs_info *mvi, u32 port); 1128c2ecf20Sopenharmony_ci void (*write_port_irq_stat)(struct mvs_info *mvi, u32 port, u32 val); 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci u32 (*read_port_irq_mask)(struct mvs_info *mvi, u32 port); 1158c2ecf20Sopenharmony_ci void (*write_port_irq_mask)(struct mvs_info *mvi, u32 port, u32 val); 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci void (*command_active)(struct mvs_info *mvi, u32 slot_idx); 1188c2ecf20Sopenharmony_ci void (*clear_srs_irq)(struct mvs_info *mvi, u8 reg_set, u8 clear_all); 1198c2ecf20Sopenharmony_ci void (*issue_stop)(struct mvs_info *mvi, enum mvs_port_type type, 1208c2ecf20Sopenharmony_ci u32 tfs); 1218c2ecf20Sopenharmony_ci void (*start_delivery)(struct mvs_info *mvi, u32 tx); 1228c2ecf20Sopenharmony_ci u32 (*rx_update)(struct mvs_info *mvi); 1238c2ecf20Sopenharmony_ci void (*int_full)(struct mvs_info *mvi); 1248c2ecf20Sopenharmony_ci u8 (*assign_reg_set)(struct mvs_info *mvi, u8 *tfs); 1258c2ecf20Sopenharmony_ci void (*free_reg_set)(struct mvs_info *mvi, u8 *tfs); 1268c2ecf20Sopenharmony_ci u32 (*prd_size)(void); 1278c2ecf20Sopenharmony_ci u32 (*prd_count)(void); 1288c2ecf20Sopenharmony_ci void (*make_prd)(struct scatterlist *scatter, int nr, void *prd); 1298c2ecf20Sopenharmony_ci void (*detect_porttype)(struct mvs_info *mvi, int i); 1308c2ecf20Sopenharmony_ci int (*oob_done)(struct mvs_info *mvi, int i); 1318c2ecf20Sopenharmony_ci void (*fix_phy_info)(struct mvs_info *mvi, int i, 1328c2ecf20Sopenharmony_ci struct sas_identify_frame *id); 1338c2ecf20Sopenharmony_ci void (*phy_work_around)(struct mvs_info *mvi, int i); 1348c2ecf20Sopenharmony_ci void (*phy_set_link_rate)(struct mvs_info *mvi, u32 phy_id, 1358c2ecf20Sopenharmony_ci struct sas_phy_linkrates *rates); 1368c2ecf20Sopenharmony_ci u32 (*phy_max_link_rate)(void); 1378c2ecf20Sopenharmony_ci void (*phy_disable)(struct mvs_info *mvi, u32 phy_id); 1388c2ecf20Sopenharmony_ci void (*phy_enable)(struct mvs_info *mvi, u32 phy_id); 1398c2ecf20Sopenharmony_ci void (*phy_reset)(struct mvs_info *mvi, u32 phy_id, int hard); 1408c2ecf20Sopenharmony_ci void (*stp_reset)(struct mvs_info *mvi, u32 phy_id); 1418c2ecf20Sopenharmony_ci void (*clear_active_cmds)(struct mvs_info *mvi); 1428c2ecf20Sopenharmony_ci u32 (*spi_read_data)(struct mvs_info *mvi); 1438c2ecf20Sopenharmony_ci void (*spi_write_data)(struct mvs_info *mvi, u32 data); 1448c2ecf20Sopenharmony_ci int (*spi_buildcmd)(struct mvs_info *mvi, 1458c2ecf20Sopenharmony_ci u32 *dwCmd, 1468c2ecf20Sopenharmony_ci u8 cmd, 1478c2ecf20Sopenharmony_ci u8 read, 1488c2ecf20Sopenharmony_ci u8 length, 1498c2ecf20Sopenharmony_ci u32 addr 1508c2ecf20Sopenharmony_ci ); 1518c2ecf20Sopenharmony_ci int (*spi_issuecmd)(struct mvs_info *mvi, u32 cmd); 1528c2ecf20Sopenharmony_ci int (*spi_waitdataready)(struct mvs_info *mvi, u32 timeout); 1538c2ecf20Sopenharmony_ci void (*dma_fix)(struct mvs_info *mvi, u32 phy_mask, 1548c2ecf20Sopenharmony_ci int buf_len, int from, void *prd); 1558c2ecf20Sopenharmony_ci void (*tune_interrupt)(struct mvs_info *mvi, u32 time); 1568c2ecf20Sopenharmony_ci void (*non_spec_ncq_error)(struct mvs_info *mvi); 1578c2ecf20Sopenharmony_ci int (*gpio_write)(struct mvs_prv_info *mvs_prv, u8 reg_type, 1588c2ecf20Sopenharmony_ci u8 reg_index, u8 reg_count, u8 *write_data); 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci}; 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_cistruct mvs_chip_info { 1638c2ecf20Sopenharmony_ci u32 n_host; 1648c2ecf20Sopenharmony_ci u32 n_phy; 1658c2ecf20Sopenharmony_ci u32 fis_offs; 1668c2ecf20Sopenharmony_ci u32 fis_count; 1678c2ecf20Sopenharmony_ci u32 srs_sz; 1688c2ecf20Sopenharmony_ci u32 sg_width; 1698c2ecf20Sopenharmony_ci u32 slot_width; 1708c2ecf20Sopenharmony_ci const struct mvs_dispatch *dispatch; 1718c2ecf20Sopenharmony_ci}; 1728c2ecf20Sopenharmony_ci#define MVS_MAX_SG (1U << mvi->chip->sg_width) 1738c2ecf20Sopenharmony_ci#define MVS_CHIP_SLOT_SZ (1U << mvi->chip->slot_width) 1748c2ecf20Sopenharmony_ci#define MVS_RX_FISL_SZ \ 1758c2ecf20Sopenharmony_ci (mvi->chip->fis_offs + (mvi->chip->fis_count * 0x100)) 1768c2ecf20Sopenharmony_ci#define MVS_CHIP_DISP (mvi->chip->dispatch) 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_cistruct mvs_err_info { 1798c2ecf20Sopenharmony_ci __le32 flags; 1808c2ecf20Sopenharmony_ci __le32 flags2; 1818c2ecf20Sopenharmony_ci}; 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_cistruct mvs_cmd_hdr { 1848c2ecf20Sopenharmony_ci __le32 flags; /* PRD tbl len; SAS, SATA ctl */ 1858c2ecf20Sopenharmony_ci __le32 lens; /* cmd, max resp frame len */ 1868c2ecf20Sopenharmony_ci __le32 tags; /* targ port xfer tag; tag */ 1878c2ecf20Sopenharmony_ci __le32 data_len; /* data xfer len */ 1888c2ecf20Sopenharmony_ci __le64 cmd_tbl; /* command table address */ 1898c2ecf20Sopenharmony_ci __le64 open_frame; /* open addr frame address */ 1908c2ecf20Sopenharmony_ci __le64 status_buf; /* status buffer address */ 1918c2ecf20Sopenharmony_ci __le64 prd_tbl; /* PRD tbl address */ 1928c2ecf20Sopenharmony_ci __le32 reserved[4]; 1938c2ecf20Sopenharmony_ci}; 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_cistruct mvs_port { 1968c2ecf20Sopenharmony_ci struct asd_sas_port sas_port; 1978c2ecf20Sopenharmony_ci u8 port_attached; 1988c2ecf20Sopenharmony_ci u8 wide_port_phymap; 1998c2ecf20Sopenharmony_ci struct list_head list; 2008c2ecf20Sopenharmony_ci}; 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_cistruct mvs_phy { 2038c2ecf20Sopenharmony_ci struct mvs_info *mvi; 2048c2ecf20Sopenharmony_ci struct mvs_port *port; 2058c2ecf20Sopenharmony_ci struct asd_sas_phy sas_phy; 2068c2ecf20Sopenharmony_ci struct sas_identify identify; 2078c2ecf20Sopenharmony_ci struct scsi_device *sdev; 2088c2ecf20Sopenharmony_ci struct timer_list timer; 2098c2ecf20Sopenharmony_ci u64 dev_sas_addr; 2108c2ecf20Sopenharmony_ci u64 att_dev_sas_addr; 2118c2ecf20Sopenharmony_ci u32 att_dev_info; 2128c2ecf20Sopenharmony_ci u32 dev_info; 2138c2ecf20Sopenharmony_ci u32 phy_type; 2148c2ecf20Sopenharmony_ci u32 phy_status; 2158c2ecf20Sopenharmony_ci u32 irq_status; 2168c2ecf20Sopenharmony_ci u32 frame_rcvd_size; 2178c2ecf20Sopenharmony_ci u8 frame_rcvd[32]; 2188c2ecf20Sopenharmony_ci u8 phy_attached; 2198c2ecf20Sopenharmony_ci u8 phy_mode; 2208c2ecf20Sopenharmony_ci u8 reserved[2]; 2218c2ecf20Sopenharmony_ci u32 phy_event; 2228c2ecf20Sopenharmony_ci enum sas_linkrate minimum_linkrate; 2238c2ecf20Sopenharmony_ci enum sas_linkrate maximum_linkrate; 2248c2ecf20Sopenharmony_ci}; 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_cistruct mvs_device { 2278c2ecf20Sopenharmony_ci struct list_head dev_entry; 2288c2ecf20Sopenharmony_ci enum sas_device_type dev_type; 2298c2ecf20Sopenharmony_ci struct mvs_info *mvi_info; 2308c2ecf20Sopenharmony_ci struct domain_device *sas_device; 2318c2ecf20Sopenharmony_ci u32 attached_phy; 2328c2ecf20Sopenharmony_ci u32 device_id; 2338c2ecf20Sopenharmony_ci u32 running_req; 2348c2ecf20Sopenharmony_ci u8 taskfileset; 2358c2ecf20Sopenharmony_ci u8 dev_status; 2368c2ecf20Sopenharmony_ci u16 reserved; 2378c2ecf20Sopenharmony_ci}; 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_ci/* Generate PHY tunning parameters */ 2408c2ecf20Sopenharmony_cistruct phy_tuning { 2418c2ecf20Sopenharmony_ci /* 1 bit, transmitter emphasis enable */ 2428c2ecf20Sopenharmony_ci u8 trans_emp_en:1; 2438c2ecf20Sopenharmony_ci /* 4 bits, transmitter emphasis amplitude */ 2448c2ecf20Sopenharmony_ci u8 trans_emp_amp:4; 2458c2ecf20Sopenharmony_ci /* 3 bits, reserved space */ 2468c2ecf20Sopenharmony_ci u8 Reserved_2bit_1:3; 2478c2ecf20Sopenharmony_ci /* 5 bits, transmitter amplitude */ 2488c2ecf20Sopenharmony_ci u8 trans_amp:5; 2498c2ecf20Sopenharmony_ci /* 2 bits, transmitter amplitude adjust */ 2508c2ecf20Sopenharmony_ci u8 trans_amp_adj:2; 2518c2ecf20Sopenharmony_ci /* 1 bit, reserved space */ 2528c2ecf20Sopenharmony_ci u8 resv_2bit_2:1; 2538c2ecf20Sopenharmony_ci /* 2 bytes, reserved space */ 2548c2ecf20Sopenharmony_ci u8 reserved[2]; 2558c2ecf20Sopenharmony_ci}; 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_cistruct ffe_control { 2588c2ecf20Sopenharmony_ci /* 4 bits, FFE Capacitor Select (value range 0~F) */ 2598c2ecf20Sopenharmony_ci u8 ffe_cap_sel:4; 2608c2ecf20Sopenharmony_ci /* 3 bits, FFE Resistor Select (value range 0~7) */ 2618c2ecf20Sopenharmony_ci u8 ffe_rss_sel:3; 2628c2ecf20Sopenharmony_ci /* 1 bit reserve*/ 2638c2ecf20Sopenharmony_ci u8 reserved:1; 2648c2ecf20Sopenharmony_ci}; 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_ci/* 2678c2ecf20Sopenharmony_ci * HBA_Info_Page is saved in Flash/NVRAM, total 256 bytes. 2688c2ecf20Sopenharmony_ci * The data area is valid only Signature="MRVL". 2698c2ecf20Sopenharmony_ci * If any member fills with 0xFF, the member is invalid. 2708c2ecf20Sopenharmony_ci */ 2718c2ecf20Sopenharmony_cistruct hba_info_page { 2728c2ecf20Sopenharmony_ci /* Dword 0 */ 2738c2ecf20Sopenharmony_ci /* 4 bytes, structure signature,should be "MRVL" at first initial */ 2748c2ecf20Sopenharmony_ci u8 signature[4]; 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_ci /* Dword 1-13 */ 2778c2ecf20Sopenharmony_ci u32 reserved1[13]; 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci /* Dword 14-29 */ 2808c2ecf20Sopenharmony_ci /* 64 bytes, SAS address for each port */ 2818c2ecf20Sopenharmony_ci u64 sas_addr[8]; 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci /* Dword 30-31 */ 2848c2ecf20Sopenharmony_ci /* 8 bytes for vanir 8 port PHY FFE seeting 2858c2ecf20Sopenharmony_ci * BIT 0~3 : FFE Capacitor select(value range 0~F) 2868c2ecf20Sopenharmony_ci * BIT 4~6 : FFE Resistor select(value range 0~7) 2878c2ecf20Sopenharmony_ci * BIT 7: reserve. 2888c2ecf20Sopenharmony_ci */ 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_ci struct ffe_control ffe_ctl[8]; 2918c2ecf20Sopenharmony_ci /* Dword 32 -43 */ 2928c2ecf20Sopenharmony_ci u32 reserved2[12]; 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_ci /* Dword 44-45 */ 2958c2ecf20Sopenharmony_ci /* 8 bytes, 0: 1.5G, 1: 3.0G, should be 0x01 at first initial */ 2968c2ecf20Sopenharmony_ci u8 phy_rate[8]; 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_ci /* Dword 46-53 */ 2998c2ecf20Sopenharmony_ci /* 32 bytes, PHY tuning parameters for each PHY*/ 3008c2ecf20Sopenharmony_ci struct phy_tuning phy_tuning[8]; 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_ci /* Dword 54-63 */ 3038c2ecf20Sopenharmony_ci u32 reserved3[10]; 3048c2ecf20Sopenharmony_ci}; /* total 256 bytes */ 3058c2ecf20Sopenharmony_ci 3068c2ecf20Sopenharmony_cistruct mvs_slot_info { 3078c2ecf20Sopenharmony_ci struct list_head entry; 3088c2ecf20Sopenharmony_ci union { 3098c2ecf20Sopenharmony_ci struct sas_task *task; 3108c2ecf20Sopenharmony_ci void *tdata; 3118c2ecf20Sopenharmony_ci }; 3128c2ecf20Sopenharmony_ci u32 n_elem; 3138c2ecf20Sopenharmony_ci u32 tx; 3148c2ecf20Sopenharmony_ci u32 slot_tag; 3158c2ecf20Sopenharmony_ci 3168c2ecf20Sopenharmony_ci /* DMA buffer for storing cmd tbl, open addr frame, status buffer, 3178c2ecf20Sopenharmony_ci * and PRD table 3188c2ecf20Sopenharmony_ci */ 3198c2ecf20Sopenharmony_ci void *buf; 3208c2ecf20Sopenharmony_ci dma_addr_t buf_dma; 3218c2ecf20Sopenharmony_ci void *response; 3228c2ecf20Sopenharmony_ci struct mvs_port *port; 3238c2ecf20Sopenharmony_ci struct mvs_device *device; 3248c2ecf20Sopenharmony_ci void *open_frame; 3258c2ecf20Sopenharmony_ci}; 3268c2ecf20Sopenharmony_ci 3278c2ecf20Sopenharmony_cistruct mvs_info { 3288c2ecf20Sopenharmony_ci unsigned long flags; 3298c2ecf20Sopenharmony_ci 3308c2ecf20Sopenharmony_ci /* host-wide lock */ 3318c2ecf20Sopenharmony_ci spinlock_t lock; 3328c2ecf20Sopenharmony_ci 3338c2ecf20Sopenharmony_ci /* our device */ 3348c2ecf20Sopenharmony_ci struct pci_dev *pdev; 3358c2ecf20Sopenharmony_ci struct device *dev; 3368c2ecf20Sopenharmony_ci 3378c2ecf20Sopenharmony_ci /* enhanced mode registers */ 3388c2ecf20Sopenharmony_ci void __iomem *regs; 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_ci /* peripheral or soc registers */ 3418c2ecf20Sopenharmony_ci void __iomem *regs_ex; 3428c2ecf20Sopenharmony_ci u8 sas_addr[SAS_ADDR_SIZE]; 3438c2ecf20Sopenharmony_ci 3448c2ecf20Sopenharmony_ci /* SCSI/SAS glue */ 3458c2ecf20Sopenharmony_ci struct sas_ha_struct *sas; 3468c2ecf20Sopenharmony_ci struct Scsi_Host *shost; 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_ci /* TX (delivery) DMA ring */ 3498c2ecf20Sopenharmony_ci __le32 *tx; 3508c2ecf20Sopenharmony_ci dma_addr_t tx_dma; 3518c2ecf20Sopenharmony_ci 3528c2ecf20Sopenharmony_ci /* cached next-producer idx */ 3538c2ecf20Sopenharmony_ci u32 tx_prod; 3548c2ecf20Sopenharmony_ci 3558c2ecf20Sopenharmony_ci /* RX (completion) DMA ring */ 3568c2ecf20Sopenharmony_ci __le32 *rx; 3578c2ecf20Sopenharmony_ci dma_addr_t rx_dma; 3588c2ecf20Sopenharmony_ci 3598c2ecf20Sopenharmony_ci /* RX consumer idx */ 3608c2ecf20Sopenharmony_ci u32 rx_cons; 3618c2ecf20Sopenharmony_ci 3628c2ecf20Sopenharmony_ci /* RX'd FIS area */ 3638c2ecf20Sopenharmony_ci __le32 *rx_fis; 3648c2ecf20Sopenharmony_ci dma_addr_t rx_fis_dma; 3658c2ecf20Sopenharmony_ci 3668c2ecf20Sopenharmony_ci /* DMA command header slots */ 3678c2ecf20Sopenharmony_ci struct mvs_cmd_hdr *slot; 3688c2ecf20Sopenharmony_ci dma_addr_t slot_dma; 3698c2ecf20Sopenharmony_ci 3708c2ecf20Sopenharmony_ci u32 chip_id; 3718c2ecf20Sopenharmony_ci const struct mvs_chip_info *chip; 3728c2ecf20Sopenharmony_ci 3738c2ecf20Sopenharmony_ci int tags_num; 3748c2ecf20Sopenharmony_ci unsigned long *tags; 3758c2ecf20Sopenharmony_ci /* further per-slot information */ 3768c2ecf20Sopenharmony_ci struct mvs_phy phy[MVS_MAX_PHYS]; 3778c2ecf20Sopenharmony_ci struct mvs_port port[MVS_MAX_PHYS]; 3788c2ecf20Sopenharmony_ci u32 id; 3798c2ecf20Sopenharmony_ci u64 sata_reg_set; 3808c2ecf20Sopenharmony_ci struct list_head *hba_list; 3818c2ecf20Sopenharmony_ci struct list_head soc_entry; 3828c2ecf20Sopenharmony_ci struct list_head wq_list; 3838c2ecf20Sopenharmony_ci unsigned long instance; 3848c2ecf20Sopenharmony_ci u16 flashid; 3858c2ecf20Sopenharmony_ci u32 flashsize; 3868c2ecf20Sopenharmony_ci u32 flashsectSize; 3878c2ecf20Sopenharmony_ci 3888c2ecf20Sopenharmony_ci void *addon; 3898c2ecf20Sopenharmony_ci struct hba_info_page hba_info_param; 3908c2ecf20Sopenharmony_ci struct mvs_device devices[MVS_MAX_DEVICES]; 3918c2ecf20Sopenharmony_ci void *bulk_buffer; 3928c2ecf20Sopenharmony_ci dma_addr_t bulk_buffer_dma; 3938c2ecf20Sopenharmony_ci void *bulk_buffer1; 3948c2ecf20Sopenharmony_ci dma_addr_t bulk_buffer_dma1; 3958c2ecf20Sopenharmony_ci#define TRASH_BUCKET_SIZE 0x20000 3968c2ecf20Sopenharmony_ci void *dma_pool; 3978c2ecf20Sopenharmony_ci struct mvs_slot_info slot_info[]; 3988c2ecf20Sopenharmony_ci}; 3998c2ecf20Sopenharmony_ci 4008c2ecf20Sopenharmony_cistruct mvs_prv_info{ 4018c2ecf20Sopenharmony_ci u8 n_host; 4028c2ecf20Sopenharmony_ci u8 n_phy; 4038c2ecf20Sopenharmony_ci u8 scan_finished; 4048c2ecf20Sopenharmony_ci u8 reserve; 4058c2ecf20Sopenharmony_ci struct mvs_info *mvi[2]; 4068c2ecf20Sopenharmony_ci struct tasklet_struct mv_tasklet; 4078c2ecf20Sopenharmony_ci}; 4088c2ecf20Sopenharmony_ci 4098c2ecf20Sopenharmony_cistruct mvs_wq { 4108c2ecf20Sopenharmony_ci struct delayed_work work_q; 4118c2ecf20Sopenharmony_ci struct mvs_info *mvi; 4128c2ecf20Sopenharmony_ci void *data; 4138c2ecf20Sopenharmony_ci int handler; 4148c2ecf20Sopenharmony_ci struct list_head entry; 4158c2ecf20Sopenharmony_ci}; 4168c2ecf20Sopenharmony_ci 4178c2ecf20Sopenharmony_cistruct mvs_task_exec_info { 4188c2ecf20Sopenharmony_ci struct sas_task *task; 4198c2ecf20Sopenharmony_ci struct mvs_cmd_hdr *hdr; 4208c2ecf20Sopenharmony_ci struct mvs_port *port; 4218c2ecf20Sopenharmony_ci u32 tag; 4228c2ecf20Sopenharmony_ci int n_elem; 4238c2ecf20Sopenharmony_ci}; 4248c2ecf20Sopenharmony_ci 4258c2ecf20Sopenharmony_ci/******************** function prototype *********************/ 4268c2ecf20Sopenharmony_civoid mvs_get_sas_addr(void *buf, u32 buflen); 4278c2ecf20Sopenharmony_civoid mvs_tag_clear(struct mvs_info *mvi, u32 tag); 4288c2ecf20Sopenharmony_civoid mvs_tag_free(struct mvs_info *mvi, u32 tag); 4298c2ecf20Sopenharmony_civoid mvs_tag_set(struct mvs_info *mvi, unsigned int tag); 4308c2ecf20Sopenharmony_ciint mvs_tag_alloc(struct mvs_info *mvi, u32 *tag_out); 4318c2ecf20Sopenharmony_civoid mvs_tag_init(struct mvs_info *mvi); 4328c2ecf20Sopenharmony_civoid mvs_iounmap(void __iomem *regs); 4338c2ecf20Sopenharmony_ciint mvs_ioremap(struct mvs_info *mvi, int bar, int bar_ex); 4348c2ecf20Sopenharmony_civoid mvs_phys_reset(struct mvs_info *mvi, u32 phy_mask, int hard); 4358c2ecf20Sopenharmony_ciint mvs_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, 4368c2ecf20Sopenharmony_ci void *funcdata); 4378c2ecf20Sopenharmony_civoid mvs_set_sas_addr(struct mvs_info *mvi, int port_id, u32 off_lo, 4388c2ecf20Sopenharmony_ci u32 off_hi, u64 sas_addr); 4398c2ecf20Sopenharmony_civoid mvs_scan_start(struct Scsi_Host *shost); 4408c2ecf20Sopenharmony_ciint mvs_scan_finished(struct Scsi_Host *shost, unsigned long time); 4418c2ecf20Sopenharmony_ciint mvs_queue_command(struct sas_task *task, gfp_t gfp_flags); 4428c2ecf20Sopenharmony_ciint mvs_abort_task(struct sas_task *task); 4438c2ecf20Sopenharmony_ciint mvs_abort_task_set(struct domain_device *dev, u8 *lun); 4448c2ecf20Sopenharmony_ciint mvs_clear_aca(struct domain_device *dev, u8 *lun); 4458c2ecf20Sopenharmony_ciint mvs_clear_task_set(struct domain_device *dev, u8 * lun); 4468c2ecf20Sopenharmony_civoid mvs_port_formed(struct asd_sas_phy *sas_phy); 4478c2ecf20Sopenharmony_civoid mvs_port_deformed(struct asd_sas_phy *sas_phy); 4488c2ecf20Sopenharmony_ciint mvs_dev_found(struct domain_device *dev); 4498c2ecf20Sopenharmony_civoid mvs_dev_gone(struct domain_device *dev); 4508c2ecf20Sopenharmony_ciint mvs_lu_reset(struct domain_device *dev, u8 *lun); 4518c2ecf20Sopenharmony_ciint mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc, u32 flags); 4528c2ecf20Sopenharmony_ciint mvs_I_T_nexus_reset(struct domain_device *dev); 4538c2ecf20Sopenharmony_ciint mvs_query_task(struct sas_task *task); 4548c2ecf20Sopenharmony_civoid mvs_release_task(struct mvs_info *mvi, 4558c2ecf20Sopenharmony_ci struct domain_device *dev); 4568c2ecf20Sopenharmony_civoid mvs_do_release_task(struct mvs_info *mvi, int phy_no, 4578c2ecf20Sopenharmony_ci struct domain_device *dev); 4588c2ecf20Sopenharmony_civoid mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events); 4598c2ecf20Sopenharmony_civoid mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st); 4608c2ecf20Sopenharmony_ciint mvs_int_rx(struct mvs_info *mvi, bool self_clear); 4618c2ecf20Sopenharmony_cistruct mvs_device *mvs_find_dev_by_reg_set(struct mvs_info *mvi, u8 reg_set); 4628c2ecf20Sopenharmony_ciint mvs_gpio_write(struct sas_ha_struct *, u8 reg_type, u8 reg_index, 4638c2ecf20Sopenharmony_ci u8 reg_count, u8 *write_data); 4648c2ecf20Sopenharmony_ci#endif 4658c2ecf20Sopenharmony_ci 466