xref: /OK3568_Linux_fs/kernel/drivers/scsi/mvumi.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun   * Marvell UMI head file
4*4882a593Smuzhiyun   *
5*4882a593Smuzhiyun   * Copyright 2011 Marvell. <jyli@marvell.com>
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #ifndef MVUMI_H
9*4882a593Smuzhiyun #define MVUMI_H
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #define MAX_BASE_ADDRESS	6
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #define VER_MAJOR		1
14*4882a593Smuzhiyun #define VER_MINOR		1
15*4882a593Smuzhiyun #define VER_OEM			0
16*4882a593Smuzhiyun #define VER_BUILD		1500
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun #define MV_DRIVER_NAME			"mvumi"
19*4882a593Smuzhiyun #define PCI_DEVICE_ID_MARVELL_MV9143	0x9143
20*4882a593Smuzhiyun #define PCI_DEVICE_ID_MARVELL_MV9580	0x9580
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun #define MVUMI_INTERNAL_CMD_WAIT_TIME	45
23*4882a593Smuzhiyun #define MVUMI_INQUIRY_LENGTH		44
24*4882a593Smuzhiyun #define MVUMI_INQUIRY_UUID_OFF		36
25*4882a593Smuzhiyun #define MVUMI_INQUIRY_UUID_LEN		8
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun #define IS_DMA64			(sizeof(dma_addr_t) == 8)
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun enum mvumi_qc_result {
30*4882a593Smuzhiyun 	MV_QUEUE_COMMAND_RESULT_SENT = 0,
31*4882a593Smuzhiyun 	MV_QUEUE_COMMAND_RESULT_NO_RESOURCE,
32*4882a593Smuzhiyun };
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun struct mvumi_hw_regs {
35*4882a593Smuzhiyun 	/* For CPU */
36*4882a593Smuzhiyun 	void *main_int_cause_reg;
37*4882a593Smuzhiyun 	void *enpointa_mask_reg;
38*4882a593Smuzhiyun 	void *enpointb_mask_reg;
39*4882a593Smuzhiyun 	void *rstoutn_en_reg;
40*4882a593Smuzhiyun 	void *ctrl_sts_reg;
41*4882a593Smuzhiyun 	void *rstoutn_mask_reg;
42*4882a593Smuzhiyun 	void *sys_soft_rst_reg;
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun 	/* For Doorbell */
45*4882a593Smuzhiyun 	void *pciea_to_arm_drbl_reg;
46*4882a593Smuzhiyun 	void *arm_to_pciea_drbl_reg;
47*4882a593Smuzhiyun 	void *arm_to_pciea_mask_reg;
48*4882a593Smuzhiyun 	void *pciea_to_arm_msg0;
49*4882a593Smuzhiyun 	void *pciea_to_arm_msg1;
50*4882a593Smuzhiyun 	void *arm_to_pciea_msg0;
51*4882a593Smuzhiyun 	void *arm_to_pciea_msg1;
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun 	/* reset register */
54*4882a593Smuzhiyun 	void *reset_request;
55*4882a593Smuzhiyun 	void *reset_enable;
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun 	/* For Message Unit */
58*4882a593Smuzhiyun 	void *inb_list_basel;
59*4882a593Smuzhiyun 	void *inb_list_baseh;
60*4882a593Smuzhiyun 	void *inb_aval_count_basel;
61*4882a593Smuzhiyun 	void *inb_aval_count_baseh;
62*4882a593Smuzhiyun 	void *inb_write_pointer;
63*4882a593Smuzhiyun 	void *inb_read_pointer;
64*4882a593Smuzhiyun 	void *outb_list_basel;
65*4882a593Smuzhiyun 	void *outb_list_baseh;
66*4882a593Smuzhiyun 	void *outb_copy_basel;
67*4882a593Smuzhiyun 	void *outb_copy_baseh;
68*4882a593Smuzhiyun 	void *outb_copy_pointer;
69*4882a593Smuzhiyun 	void *outb_read_pointer;
70*4882a593Smuzhiyun 	void *inb_isr_cause;
71*4882a593Smuzhiyun 	void *outb_isr_cause;
72*4882a593Smuzhiyun 	void *outb_coal_cfg;
73*4882a593Smuzhiyun 	void *outb_coal_timeout;
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun 	/* Bit setting for HW */
76*4882a593Smuzhiyun 	u32 int_comaout;
77*4882a593Smuzhiyun 	u32 int_comaerr;
78*4882a593Smuzhiyun 	u32 int_dl_cpu2pciea;
79*4882a593Smuzhiyun 	u32 int_mu;
80*4882a593Smuzhiyun 	u32 int_drbl_int_mask;
81*4882a593Smuzhiyun 	u32 int_main_int_mask;
82*4882a593Smuzhiyun 	u32 cl_pointer_toggle;
83*4882a593Smuzhiyun 	u32 cl_slot_num_mask;
84*4882a593Smuzhiyun 	u32 clic_irq;
85*4882a593Smuzhiyun 	u32 clic_in_err;
86*4882a593Smuzhiyun 	u32 clic_out_err;
87*4882a593Smuzhiyun };
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun struct mvumi_dyn_list_entry {
90*4882a593Smuzhiyun 	u32 src_low_addr;
91*4882a593Smuzhiyun 	u32 src_high_addr;
92*4882a593Smuzhiyun 	u32 if_length;
93*4882a593Smuzhiyun 	u32 reserve;
94*4882a593Smuzhiyun };
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun #define SCSI_CMD_MARVELL_SPECIFIC	0xE1
97*4882a593Smuzhiyun #define CDB_CORE_MODULE			0x1
98*4882a593Smuzhiyun #define CDB_CORE_SHUTDOWN		0xB
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun enum {
101*4882a593Smuzhiyun 	DRBL_HANDSHAKE			= 1 << 0,
102*4882a593Smuzhiyun 	DRBL_SOFT_RESET			= 1 << 1,
103*4882a593Smuzhiyun 	DRBL_BUS_CHANGE			= 1 << 2,
104*4882a593Smuzhiyun 	DRBL_EVENT_NOTIFY		= 1 << 3,
105*4882a593Smuzhiyun 	DRBL_MU_RESET			= 1 << 4,
106*4882a593Smuzhiyun 	DRBL_HANDSHAKE_ISR		= DRBL_HANDSHAKE,
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun 	/*
109*4882a593Smuzhiyun 	* Command flag is the flag for the CDB command itself
110*4882a593Smuzhiyun 	*/
111*4882a593Smuzhiyun 	/* 1-non data; 0-data command */
112*4882a593Smuzhiyun 	CMD_FLAG_NON_DATA		= 1 << 0,
113*4882a593Smuzhiyun 	CMD_FLAG_DMA			= 1 << 1,
114*4882a593Smuzhiyun 	CMD_FLAG_PIO			= 1 << 2,
115*4882a593Smuzhiyun 	/* 1-host read data */
116*4882a593Smuzhiyun 	CMD_FLAG_DATA_IN		= 1 << 3,
117*4882a593Smuzhiyun 	/* 1-host write data */
118*4882a593Smuzhiyun 	CMD_FLAG_DATA_OUT		= 1 << 4,
119*4882a593Smuzhiyun 	CMD_FLAG_PRDT_IN_HOST		= 1 << 5,
120*4882a593Smuzhiyun };
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun #define APICDB0_EVENT			0xF4
123*4882a593Smuzhiyun #define APICDB1_EVENT_GETEVENT		0
124*4882a593Smuzhiyun #define APICDB1_HOST_GETEVENT		1
125*4882a593Smuzhiyun #define MAX_EVENTS_RETURNED		6
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun #define DEVICE_OFFLINE	0
128*4882a593Smuzhiyun #define DEVICE_ONLINE	1
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun struct mvumi_hotplug_event {
131*4882a593Smuzhiyun 	u16 size;
132*4882a593Smuzhiyun 	u8 dummy[2];
133*4882a593Smuzhiyun 	u8 bitmap[];
134*4882a593Smuzhiyun };
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun struct mvumi_driver_event {
137*4882a593Smuzhiyun 	u32	time_stamp;
138*4882a593Smuzhiyun 	u32	sequence_no;
139*4882a593Smuzhiyun 	u32	event_id;
140*4882a593Smuzhiyun 	u8	severity;
141*4882a593Smuzhiyun 	u8	param_count;
142*4882a593Smuzhiyun 	u16	device_id;
143*4882a593Smuzhiyun 	u32	params[4];
144*4882a593Smuzhiyun 	u8	sense_data_length;
145*4882a593Smuzhiyun 	u8	Reserved1;
146*4882a593Smuzhiyun 	u8	sense_data[30];
147*4882a593Smuzhiyun };
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun struct mvumi_event_req {
150*4882a593Smuzhiyun 	unsigned char	count;
151*4882a593Smuzhiyun 	unsigned char	reserved[3];
152*4882a593Smuzhiyun 	struct mvumi_driver_event  events[MAX_EVENTS_RETURNED];
153*4882a593Smuzhiyun };
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun struct mvumi_events_wq {
156*4882a593Smuzhiyun 	struct work_struct work_q;
157*4882a593Smuzhiyun 	struct mvumi_hba *mhba;
158*4882a593Smuzhiyun 	unsigned int event;
159*4882a593Smuzhiyun 	void *param;
160*4882a593Smuzhiyun };
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun #define HS_CAPABILITY_SUPPORT_COMPACT_SG	(1U << 4)
163*4882a593Smuzhiyun #define HS_CAPABILITY_SUPPORT_PRD_HOST		(1U << 5)
164*4882a593Smuzhiyun #define HS_CAPABILITY_SUPPORT_DYN_SRC		(1U << 6)
165*4882a593Smuzhiyun #define HS_CAPABILITY_NEW_PAGE_IO_DEPTH_DEF	(1U << 14)
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun #define MVUMI_MAX_SG_ENTRY	32
168*4882a593Smuzhiyun #define SGD_EOT			(1L << 27)
169*4882a593Smuzhiyun #define SGD_EOT_CP		(1L << 22)
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun struct mvumi_sgl {
172*4882a593Smuzhiyun 	u32	baseaddr_l;
173*4882a593Smuzhiyun 	u32	baseaddr_h;
174*4882a593Smuzhiyun 	u32	flags;
175*4882a593Smuzhiyun 	u32	size;
176*4882a593Smuzhiyun };
177*4882a593Smuzhiyun struct mvumi_compact_sgl {
178*4882a593Smuzhiyun 	u32	baseaddr_l;
179*4882a593Smuzhiyun 	u32	baseaddr_h;
180*4882a593Smuzhiyun 	u32	flags;
181*4882a593Smuzhiyun };
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun #define GET_COMPACT_SGD_SIZE(sgd)	\
184*4882a593Smuzhiyun 	((((struct mvumi_compact_sgl *)(sgd))->flags) & 0x3FFFFFL)
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun #define SET_COMPACT_SGD_SIZE(sgd, sz) do {			\
187*4882a593Smuzhiyun 	(((struct mvumi_compact_sgl *)(sgd))->flags) &= ~0x3FFFFFL;	\
188*4882a593Smuzhiyun 	(((struct mvumi_compact_sgl *)(sgd))->flags) |= (sz);		\
189*4882a593Smuzhiyun } while (0)
190*4882a593Smuzhiyun #define sgd_getsz(_mhba, sgd, sz) do {				\
191*4882a593Smuzhiyun 	if (_mhba->hba_capability & HS_CAPABILITY_SUPPORT_COMPACT_SG)	\
192*4882a593Smuzhiyun 		(sz) = GET_COMPACT_SGD_SIZE(sgd);	\
193*4882a593Smuzhiyun 	else \
194*4882a593Smuzhiyun 		(sz) = (sgd)->size;			\
195*4882a593Smuzhiyun } while (0)
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun #define sgd_setsz(_mhba, sgd, sz) do {				\
198*4882a593Smuzhiyun 	if (_mhba->hba_capability & HS_CAPABILITY_SUPPORT_COMPACT_SG)	\
199*4882a593Smuzhiyun 		SET_COMPACT_SGD_SIZE(sgd, sz);		\
200*4882a593Smuzhiyun 	else \
201*4882a593Smuzhiyun 		(sgd)->size = (sz);			\
202*4882a593Smuzhiyun } while (0)
203*4882a593Smuzhiyun 
204*4882a593Smuzhiyun #define sgd_inc(_mhba, sgd) do {	\
205*4882a593Smuzhiyun 	if (_mhba->hba_capability & HS_CAPABILITY_SUPPORT_COMPACT_SG)	\
206*4882a593Smuzhiyun 		sgd = (struct mvumi_sgl *)(((unsigned char *) (sgd)) + 12); \
207*4882a593Smuzhiyun 	else \
208*4882a593Smuzhiyun 		sgd = (struct mvumi_sgl *)(((unsigned char *) (sgd)) + 16); \
209*4882a593Smuzhiyun } while (0)
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun struct mvumi_res {
212*4882a593Smuzhiyun 	struct list_head entry;
213*4882a593Smuzhiyun 	dma_addr_t bus_addr;
214*4882a593Smuzhiyun 	void *virt_addr;
215*4882a593Smuzhiyun 	unsigned int size;
216*4882a593Smuzhiyun 	unsigned short type;	/* enum Resource_Type */
217*4882a593Smuzhiyun };
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun /* Resource type */
220*4882a593Smuzhiyun enum resource_type {
221*4882a593Smuzhiyun 	RESOURCE_CACHED_MEMORY = 0,
222*4882a593Smuzhiyun 	RESOURCE_UNCACHED_MEMORY
223*4882a593Smuzhiyun };
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun struct mvumi_sense_data {
226*4882a593Smuzhiyun 	u8 error_code:7;
227*4882a593Smuzhiyun 	u8 valid:1;
228*4882a593Smuzhiyun 	u8 segment_number;
229*4882a593Smuzhiyun 	u8 sense_key:4;
230*4882a593Smuzhiyun 	u8 reserved:1;
231*4882a593Smuzhiyun 	u8 incorrect_length:1;
232*4882a593Smuzhiyun 	u8 end_of_media:1;
233*4882a593Smuzhiyun 	u8 file_mark:1;
234*4882a593Smuzhiyun 	u8 information[4];
235*4882a593Smuzhiyun 	u8 additional_sense_length;
236*4882a593Smuzhiyun 	u8 command_specific_information[4];
237*4882a593Smuzhiyun 	u8 additional_sense_code;
238*4882a593Smuzhiyun 	u8 additional_sense_code_qualifier;
239*4882a593Smuzhiyun 	u8 field_replaceable_unit_code;
240*4882a593Smuzhiyun 	u8 sense_key_specific[3];
241*4882a593Smuzhiyun };
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun /* Request initiator must set the status to REQ_STATUS_PENDING. */
244*4882a593Smuzhiyun #define REQ_STATUS_PENDING		0x80
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun struct mvumi_cmd {
247*4882a593Smuzhiyun 	struct list_head queue_pointer;
248*4882a593Smuzhiyun 	struct mvumi_msg_frame *frame;
249*4882a593Smuzhiyun 	dma_addr_t frame_phys;
250*4882a593Smuzhiyun 	struct scsi_cmnd *scmd;
251*4882a593Smuzhiyun 	atomic_t sync_cmd;
252*4882a593Smuzhiyun 	void *data_buf;
253*4882a593Smuzhiyun 	unsigned short request_id;
254*4882a593Smuzhiyun 	unsigned char cmd_status;
255*4882a593Smuzhiyun };
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun /*
258*4882a593Smuzhiyun  * the function type of the in bound frame
259*4882a593Smuzhiyun  */
260*4882a593Smuzhiyun #define CL_FUN_SCSI_CMD			0x1
261*4882a593Smuzhiyun 
262*4882a593Smuzhiyun struct mvumi_msg_frame {
263*4882a593Smuzhiyun 	u16 device_id;
264*4882a593Smuzhiyun 	u16 tag;
265*4882a593Smuzhiyun 	u8 cmd_flag;
266*4882a593Smuzhiyun 	u8 req_function;
267*4882a593Smuzhiyun 	u8 cdb_length;
268*4882a593Smuzhiyun 	u8 sg_counts;
269*4882a593Smuzhiyun 	u32 data_transfer_length;
270*4882a593Smuzhiyun 	u16 request_id;
271*4882a593Smuzhiyun 	u16 reserved1;
272*4882a593Smuzhiyun 	u8 cdb[MAX_COMMAND_SIZE];
273*4882a593Smuzhiyun 	u32 payload[1];
274*4882a593Smuzhiyun };
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun /*
277*4882a593Smuzhiyun  * the respond flag for data_payload of the out bound frame
278*4882a593Smuzhiyun  */
279*4882a593Smuzhiyun #define CL_RSP_FLAG_NODATA		0x0
280*4882a593Smuzhiyun #define CL_RSP_FLAG_SENSEDATA		0x1
281*4882a593Smuzhiyun 
282*4882a593Smuzhiyun struct mvumi_rsp_frame {
283*4882a593Smuzhiyun 	u16 device_id;
284*4882a593Smuzhiyun 	u16 tag;
285*4882a593Smuzhiyun 	u8 req_status;
286*4882a593Smuzhiyun 	u8 rsp_flag;	/* Indicates the type of Data_Payload.*/
287*4882a593Smuzhiyun 	u16 request_id;
288*4882a593Smuzhiyun 	u32 payload[1];
289*4882a593Smuzhiyun };
290*4882a593Smuzhiyun 
291*4882a593Smuzhiyun struct mvumi_ob_data {
292*4882a593Smuzhiyun 	struct list_head list;
293*4882a593Smuzhiyun 	unsigned char data[];
294*4882a593Smuzhiyun };
295*4882a593Smuzhiyun 
296*4882a593Smuzhiyun struct version_info {
297*4882a593Smuzhiyun 	u32 ver_major;
298*4882a593Smuzhiyun 	u32 ver_minor;
299*4882a593Smuzhiyun 	u32 ver_oem;
300*4882a593Smuzhiyun 	u32 ver_build;
301*4882a593Smuzhiyun };
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun #define FW_MAX_DELAY			30
304*4882a593Smuzhiyun #define MVUMI_FW_BUSY			(1U << 0)
305*4882a593Smuzhiyun #define MVUMI_FW_ATTACH			(1U << 1)
306*4882a593Smuzhiyun #define MVUMI_FW_ALLOC			(1U << 2)
307*4882a593Smuzhiyun 
308*4882a593Smuzhiyun /*
309*4882a593Smuzhiyun  * State is the state of the MU
310*4882a593Smuzhiyun  */
311*4882a593Smuzhiyun #define FW_STATE_IDLE			0
312*4882a593Smuzhiyun #define FW_STATE_STARTING		1
313*4882a593Smuzhiyun #define FW_STATE_HANDSHAKING		2
314*4882a593Smuzhiyun #define FW_STATE_STARTED		3
315*4882a593Smuzhiyun #define FW_STATE_ABORT			4
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun #define HANDSHAKE_SIGNATURE		0x5A5A5A5AL
318*4882a593Smuzhiyun #define HANDSHAKE_READYSTATE		0x55AA5AA5L
319*4882a593Smuzhiyun #define HANDSHAKE_DONESTATE		0x55AAA55AL
320*4882a593Smuzhiyun 
321*4882a593Smuzhiyun /* HandShake Status definition */
322*4882a593Smuzhiyun #define HS_STATUS_OK			1
323*4882a593Smuzhiyun #define HS_STATUS_ERR			2
324*4882a593Smuzhiyun #define HS_STATUS_INVALID		3
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun /* HandShake State/Cmd definition */
327*4882a593Smuzhiyun #define HS_S_START			1
328*4882a593Smuzhiyun #define HS_S_RESET			2
329*4882a593Smuzhiyun #define HS_S_PAGE_ADDR			3
330*4882a593Smuzhiyun #define HS_S_QUERY_PAGE			4
331*4882a593Smuzhiyun #define HS_S_SEND_PAGE			5
332*4882a593Smuzhiyun #define HS_S_END			6
333*4882a593Smuzhiyun #define HS_S_ABORT			7
334*4882a593Smuzhiyun #define HS_PAGE_VERIFY_SIZE		128
335*4882a593Smuzhiyun 
336*4882a593Smuzhiyun #define HS_GET_STATE(a)			(a & 0xFFFF)
337*4882a593Smuzhiyun #define HS_GET_STATUS(a)		((a & 0xFFFF0000) >> 16)
338*4882a593Smuzhiyun #define HS_SET_STATE(a, b)		(a |= (b & 0xFFFF))
339*4882a593Smuzhiyun #define HS_SET_STATUS(a, b)		(a |= ((b & 0xFFFF) << 16))
340*4882a593Smuzhiyun 
341*4882a593Smuzhiyun /* handshake frame */
342*4882a593Smuzhiyun struct mvumi_hs_frame {
343*4882a593Smuzhiyun 	u16 size;
344*4882a593Smuzhiyun 	/* host information */
345*4882a593Smuzhiyun 	u8 host_type;
346*4882a593Smuzhiyun 	u8 reserved_1[1];
347*4882a593Smuzhiyun 	struct version_info host_ver; /* bios or driver version */
348*4882a593Smuzhiyun 
349*4882a593Smuzhiyun 	/* controller information */
350*4882a593Smuzhiyun 	u32 system_io_bus;
351*4882a593Smuzhiyun 	u32 slot_number;
352*4882a593Smuzhiyun 	u32 intr_level;
353*4882a593Smuzhiyun 	u32 intr_vector;
354*4882a593Smuzhiyun 
355*4882a593Smuzhiyun 	/* communication list configuration */
356*4882a593Smuzhiyun 	u32 ib_baseaddr_l;
357*4882a593Smuzhiyun 	u32 ib_baseaddr_h;
358*4882a593Smuzhiyun 	u32 ob_baseaddr_l;
359*4882a593Smuzhiyun 	u32 ob_baseaddr_h;
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun 	u8 ib_entry_size;
362*4882a593Smuzhiyun 	u8 ob_entry_size;
363*4882a593Smuzhiyun 	u8 ob_depth;
364*4882a593Smuzhiyun 	u8 ib_depth;
365*4882a593Smuzhiyun 
366*4882a593Smuzhiyun 	/* system time */
367*4882a593Smuzhiyun 	u64 seconds_since1970;
368*4882a593Smuzhiyun };
369*4882a593Smuzhiyun 
370*4882a593Smuzhiyun struct mvumi_hs_header {
371*4882a593Smuzhiyun 	u8	page_code;
372*4882a593Smuzhiyun 	u8	checksum;
373*4882a593Smuzhiyun 	u16	frame_length;
374*4882a593Smuzhiyun 	u32	frame_content[1];
375*4882a593Smuzhiyun };
376*4882a593Smuzhiyun 
377*4882a593Smuzhiyun /*
378*4882a593Smuzhiyun  * the page code type of the handshake header
379*4882a593Smuzhiyun  */
380*4882a593Smuzhiyun #define HS_PAGE_FIRM_CAP	0x1
381*4882a593Smuzhiyun #define HS_PAGE_HOST_INFO	0x2
382*4882a593Smuzhiyun #define HS_PAGE_FIRM_CTL	0x3
383*4882a593Smuzhiyun #define HS_PAGE_CL_INFO		0x4
384*4882a593Smuzhiyun #define HS_PAGE_TOTAL		0x5
385*4882a593Smuzhiyun 
386*4882a593Smuzhiyun #define HSP_SIZE(i)	sizeof(struct mvumi_hs_page##i)
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun #define HSP_MAX_SIZE ({					\
389*4882a593Smuzhiyun 	int size, m1, m2;				\
390*4882a593Smuzhiyun 	m1 = max(HSP_SIZE(1), HSP_SIZE(3));		\
391*4882a593Smuzhiyun 	m2 = max(HSP_SIZE(2), HSP_SIZE(4));		\
392*4882a593Smuzhiyun 	size = max(m1, m2);				\
393*4882a593Smuzhiyun 	size;						\
394*4882a593Smuzhiyun })
395*4882a593Smuzhiyun 
396*4882a593Smuzhiyun /* The format of the page code for Firmware capability */
397*4882a593Smuzhiyun struct mvumi_hs_page1 {
398*4882a593Smuzhiyun 	u8 pagecode;
399*4882a593Smuzhiyun 	u8 checksum;
400*4882a593Smuzhiyun 	u16 frame_length;
401*4882a593Smuzhiyun 
402*4882a593Smuzhiyun 	u16 number_of_ports;
403*4882a593Smuzhiyun 	u16 max_devices_support;
404*4882a593Smuzhiyun 	u16 max_io_support;
405*4882a593Smuzhiyun 	u16 umi_ver;
406*4882a593Smuzhiyun 	u32 max_transfer_size;
407*4882a593Smuzhiyun 	struct version_info fw_ver;
408*4882a593Smuzhiyun 	u8 cl_in_max_entry_size;
409*4882a593Smuzhiyun 	u8 cl_out_max_entry_size;
410*4882a593Smuzhiyun 	u8 cl_inout_list_depth;
411*4882a593Smuzhiyun 	u8 total_pages;
412*4882a593Smuzhiyun 	u16 capability;
413*4882a593Smuzhiyun 	u16 reserved1;
414*4882a593Smuzhiyun };
415*4882a593Smuzhiyun 
416*4882a593Smuzhiyun /* The format of the page code for Host information */
417*4882a593Smuzhiyun struct mvumi_hs_page2 {
418*4882a593Smuzhiyun 	u8 pagecode;
419*4882a593Smuzhiyun 	u8 checksum;
420*4882a593Smuzhiyun 	u16 frame_length;
421*4882a593Smuzhiyun 
422*4882a593Smuzhiyun 	u8 host_type;
423*4882a593Smuzhiyun 	u8 host_cap;
424*4882a593Smuzhiyun 	u8 reserved[2];
425*4882a593Smuzhiyun 	struct version_info host_ver;
426*4882a593Smuzhiyun 	u32 system_io_bus;
427*4882a593Smuzhiyun 	u32 slot_number;
428*4882a593Smuzhiyun 	u32 intr_level;
429*4882a593Smuzhiyun 	u32 intr_vector;
430*4882a593Smuzhiyun 	u64 seconds_since1970;
431*4882a593Smuzhiyun };
432*4882a593Smuzhiyun 
433*4882a593Smuzhiyun /* The format of the page code for firmware control  */
434*4882a593Smuzhiyun struct mvumi_hs_page3 {
435*4882a593Smuzhiyun 	u8	pagecode;
436*4882a593Smuzhiyun 	u8	checksum;
437*4882a593Smuzhiyun 	u16	frame_length;
438*4882a593Smuzhiyun 	u16	control;
439*4882a593Smuzhiyun 	u8	reserved[2];
440*4882a593Smuzhiyun 	u32	host_bufferaddr_l;
441*4882a593Smuzhiyun 	u32	host_bufferaddr_h;
442*4882a593Smuzhiyun 	u32	host_eventaddr_l;
443*4882a593Smuzhiyun 	u32	host_eventaddr_h;
444*4882a593Smuzhiyun };
445*4882a593Smuzhiyun 
446*4882a593Smuzhiyun struct mvumi_hs_page4 {
447*4882a593Smuzhiyun 	u8	pagecode;
448*4882a593Smuzhiyun 	u8	checksum;
449*4882a593Smuzhiyun 	u16	frame_length;
450*4882a593Smuzhiyun 	u32	ib_baseaddr_l;
451*4882a593Smuzhiyun 	u32	ib_baseaddr_h;
452*4882a593Smuzhiyun 	u32	ob_baseaddr_l;
453*4882a593Smuzhiyun 	u32	ob_baseaddr_h;
454*4882a593Smuzhiyun 	u8	ib_entry_size;
455*4882a593Smuzhiyun 	u8	ob_entry_size;
456*4882a593Smuzhiyun 	u8	ob_depth;
457*4882a593Smuzhiyun 	u8	ib_depth;
458*4882a593Smuzhiyun };
459*4882a593Smuzhiyun 
460*4882a593Smuzhiyun struct mvumi_tag {
461*4882a593Smuzhiyun 	unsigned short *stack;
462*4882a593Smuzhiyun 	unsigned short top;
463*4882a593Smuzhiyun 	unsigned short size;
464*4882a593Smuzhiyun };
465*4882a593Smuzhiyun 
466*4882a593Smuzhiyun struct mvumi_device {
467*4882a593Smuzhiyun 	struct list_head list;
468*4882a593Smuzhiyun 	struct scsi_device *sdev;
469*4882a593Smuzhiyun 	u64	wwid;
470*4882a593Smuzhiyun 	u8	dev_type;
471*4882a593Smuzhiyun 	int	id;
472*4882a593Smuzhiyun };
473*4882a593Smuzhiyun 
474*4882a593Smuzhiyun struct mvumi_hba {
475*4882a593Smuzhiyun 	void *base_addr[MAX_BASE_ADDRESS];
476*4882a593Smuzhiyun 	u32 pci_base[MAX_BASE_ADDRESS];
477*4882a593Smuzhiyun 	void *mmio;
478*4882a593Smuzhiyun 	struct list_head cmd_pool;
479*4882a593Smuzhiyun 	struct Scsi_Host *shost;
480*4882a593Smuzhiyun 	wait_queue_head_t int_cmd_wait_q;
481*4882a593Smuzhiyun 	struct pci_dev *pdev;
482*4882a593Smuzhiyun 	unsigned int unique_id;
483*4882a593Smuzhiyun 	atomic_t fw_outstanding;
484*4882a593Smuzhiyun 	struct mvumi_instance_template *instancet;
485*4882a593Smuzhiyun 
486*4882a593Smuzhiyun 	void *ib_list;
487*4882a593Smuzhiyun 	dma_addr_t ib_list_phys;
488*4882a593Smuzhiyun 
489*4882a593Smuzhiyun 	void *ib_frame;
490*4882a593Smuzhiyun 	dma_addr_t ib_frame_phys;
491*4882a593Smuzhiyun 
492*4882a593Smuzhiyun 	void *ob_list;
493*4882a593Smuzhiyun 	dma_addr_t ob_list_phys;
494*4882a593Smuzhiyun 
495*4882a593Smuzhiyun 	void *ib_shadow;
496*4882a593Smuzhiyun 	dma_addr_t ib_shadow_phys;
497*4882a593Smuzhiyun 
498*4882a593Smuzhiyun 	void *ob_shadow;
499*4882a593Smuzhiyun 	dma_addr_t ob_shadow_phys;
500*4882a593Smuzhiyun 
501*4882a593Smuzhiyun 	void *handshake_page;
502*4882a593Smuzhiyun 	dma_addr_t handshake_page_phys;
503*4882a593Smuzhiyun 
504*4882a593Smuzhiyun 	unsigned int global_isr;
505*4882a593Smuzhiyun 	unsigned int isr_status;
506*4882a593Smuzhiyun 
507*4882a593Smuzhiyun 	unsigned short max_sge;
508*4882a593Smuzhiyun 	unsigned short max_target_id;
509*4882a593Smuzhiyun 	unsigned char *target_map;
510*4882a593Smuzhiyun 	unsigned int max_io;
511*4882a593Smuzhiyun 	unsigned int list_num_io;
512*4882a593Smuzhiyun 	unsigned int ib_max_size;
513*4882a593Smuzhiyun 	unsigned int ob_max_size;
514*4882a593Smuzhiyun 	unsigned int ib_max_size_setting;
515*4882a593Smuzhiyun 	unsigned int ob_max_size_setting;
516*4882a593Smuzhiyun 	unsigned int max_transfer_size;
517*4882a593Smuzhiyun 	unsigned char hba_total_pages;
518*4882a593Smuzhiyun 	unsigned char fw_flag;
519*4882a593Smuzhiyun 	unsigned char request_id_enabled;
520*4882a593Smuzhiyun 	unsigned char eot_flag;
521*4882a593Smuzhiyun 	unsigned short hba_capability;
522*4882a593Smuzhiyun 	unsigned short io_seq;
523*4882a593Smuzhiyun 
524*4882a593Smuzhiyun 	unsigned int ib_cur_slot;
525*4882a593Smuzhiyun 	unsigned int ob_cur_slot;
526*4882a593Smuzhiyun 	unsigned int fw_state;
527*4882a593Smuzhiyun 	struct mutex sas_discovery_mutex;
528*4882a593Smuzhiyun 
529*4882a593Smuzhiyun 	struct list_head ob_data_list;
530*4882a593Smuzhiyun 	struct list_head free_ob_list;
531*4882a593Smuzhiyun 	struct list_head res_list;
532*4882a593Smuzhiyun 	struct list_head waiting_req_list;
533*4882a593Smuzhiyun 
534*4882a593Smuzhiyun 	struct mvumi_tag tag_pool;
535*4882a593Smuzhiyun 	struct mvumi_cmd **tag_cmd;
536*4882a593Smuzhiyun 	struct mvumi_hw_regs *regs;
537*4882a593Smuzhiyun 	struct mutex device_lock;
538*4882a593Smuzhiyun 	struct list_head mhba_dev_list;
539*4882a593Smuzhiyun 	struct list_head shost_dev_list;
540*4882a593Smuzhiyun 	struct task_struct *dm_thread;
541*4882a593Smuzhiyun 	atomic_t pnp_count;
542*4882a593Smuzhiyun };
543*4882a593Smuzhiyun 
544*4882a593Smuzhiyun struct mvumi_instance_template {
545*4882a593Smuzhiyun 	void (*fire_cmd) (struct mvumi_hba *, struct mvumi_cmd *);
546*4882a593Smuzhiyun 	void (*enable_intr) (struct mvumi_hba *);
547*4882a593Smuzhiyun 	void (*disable_intr) (struct mvumi_hba *);
548*4882a593Smuzhiyun 	int (*clear_intr) (void *);
549*4882a593Smuzhiyun 	unsigned int (*read_fw_status_reg) (struct mvumi_hba *);
550*4882a593Smuzhiyun 	unsigned int (*check_ib_list) (struct mvumi_hba *);
551*4882a593Smuzhiyun 	int (*check_ob_list) (struct mvumi_hba *, unsigned int *,
552*4882a593Smuzhiyun 			      unsigned int *);
553*4882a593Smuzhiyun 	int (*reset_host) (struct mvumi_hba *);
554*4882a593Smuzhiyun };
555*4882a593Smuzhiyun 
556*4882a593Smuzhiyun extern struct timezone sys_tz;
557*4882a593Smuzhiyun #endif
558