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