1/*
2  * Marvell UMI head file
3  *
4  * Copyright 2011 Marvell. <jyli@marvell.com>
5  *
6  * This file is licensed under GPLv2.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; version 2 of the
11  * License.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21  * USA
22 */
23
24#ifndef MVUMI_H
25#define MVUMI_H
26
27#define MAX_BASE_ADDRESS	6
28
29#define VER_MAJOR		1
30#define VER_MINOR		1
31#define VER_OEM			0
32#define VER_BUILD		1500
33
34#define MV_DRIVER_NAME			"mvumi"
35#define PCI_VENDOR_ID_MARVELL_2		0x1b4b
36#define PCI_DEVICE_ID_MARVELL_MV9143	0x9143
37
38#define MVUMI_INTERNAL_CMD_WAIT_TIME	45
39
40#define IS_DMA64			(sizeof(dma_addr_t) == 8)
41
42enum mvumi_qc_result {
43	MV_QUEUE_COMMAND_RESULT_SENT	= 0,
44	MV_QUEUE_COMMAND_RESULT_NO_RESOURCE,
45};
46
47enum {
48	/*******************************************/
49
50	/* ARM Mbus Registers Map	*/
51
52	/*******************************************/
53	CPU_MAIN_INT_CAUSE_REG	= 0x20200,
54	CPU_MAIN_IRQ_MASK_REG	= 0x20204,
55	CPU_MAIN_FIQ_MASK_REG	= 0x20208,
56	CPU_ENPOINTA_MASK_REG	= 0x2020C,
57	CPU_ENPOINTB_MASK_REG	= 0x20210,
58
59	INT_MAP_COMAERR		= 1 << 6,
60	INT_MAP_COMAIN		= 1 << 7,
61	INT_MAP_COMAOUT		= 1 << 8,
62	INT_MAP_COMBERR		= 1 << 9,
63	INT_MAP_COMBIN		= 1 << 10,
64	INT_MAP_COMBOUT		= 1 << 11,
65
66	INT_MAP_COMAINT	= (INT_MAP_COMAOUT | INT_MAP_COMAERR),
67	INT_MAP_COMBINT	= (INT_MAP_COMBOUT | INT_MAP_COMBIN | INT_MAP_COMBERR),
68
69	INT_MAP_DL_PCIEA2CPU	= 1 << 0,
70	INT_MAP_DL_CPU2PCIEA	= 1 << 1,
71
72	/***************************************/
73
74	/* ARM Doorbell Registers Map		*/
75
76	/***************************************/
77	CPU_PCIEA_TO_ARM_DRBL_REG	= 0x20400,
78	CPU_PCIEA_TO_ARM_MASK_REG	= 0x20404,
79	CPU_ARM_TO_PCIEA_DRBL_REG	= 0x20408,
80	CPU_ARM_TO_PCIEA_MASK_REG	= 0x2040C,
81
82	DRBL_HANDSHAKE			= 1 << 0,
83	DRBL_SOFT_RESET			= 1 << 1,
84	DRBL_BUS_CHANGE			= 1 << 2,
85	DRBL_EVENT_NOTIFY		= 1 << 3,
86	DRBL_MU_RESET			= 1 << 4,
87	DRBL_HANDSHAKE_ISR		= DRBL_HANDSHAKE,
88
89	CPU_PCIEA_TO_ARM_MSG0		= 0x20430,
90	CPU_PCIEA_TO_ARM_MSG1		= 0x20434,
91	CPU_ARM_TO_PCIEA_MSG0		= 0x20438,
92	CPU_ARM_TO_PCIEA_MSG1		= 0x2043C,
93
94	/*******************************************/
95
96	/* ARM Communication List Registers Map    */
97
98	/*******************************************/
99	CLA_INB_LIST_BASEL		= 0x500,
100	CLA_INB_LIST_BASEH		= 0x504,
101	CLA_INB_AVAL_COUNT_BASEL	= 0x508,
102	CLA_INB_AVAL_COUNT_BASEH	= 0x50C,
103	CLA_INB_DESTI_LIST_BASEL	= 0x510,
104	CLA_INB_DESTI_LIST_BASEH	= 0x514,
105	CLA_INB_WRITE_POINTER		= 0x518,
106	CLA_INB_READ_POINTER		= 0x51C,
107
108	CLA_OUTB_LIST_BASEL		= 0x530,
109	CLA_OUTB_LIST_BASEH		= 0x534,
110	CLA_OUTB_SOURCE_LIST_BASEL	= 0x538,
111	CLA_OUTB_SOURCE_LIST_BASEH	= 0x53C,
112	CLA_OUTB_COPY_POINTER		= 0x544,
113	CLA_OUTB_READ_POINTER		= 0x548,
114
115	CLA_ISR_CAUSE			= 0x560,
116	CLA_ISR_MASK			= 0x564,
117
118	INT_MAP_MU		= (INT_MAP_DL_CPU2PCIEA | INT_MAP_COMAINT),
119
120	CL_POINTER_TOGGLE		= 1 << 12,
121
122	CLIC_IN_IRQ			= 1 << 0,
123	CLIC_OUT_IRQ			= 1 << 1,
124	CLIC_IN_ERR_IRQ			= 1 << 8,
125	CLIC_OUT_ERR_IRQ		= 1 << 12,
126
127	CL_SLOT_NUM_MASK		= 0xFFF,
128
129	/*
130	* Command flag is the flag for the CDB command itself
131	*/
132	/* 1-non data; 0-data command */
133	CMD_FLAG_NON_DATA		= 1 << 0,
134	CMD_FLAG_DMA			= 1 << 1,
135	CMD_FLAG_PIO			= 1 << 2,
136	/* 1-host read data */
137	CMD_FLAG_DATA_IN		= 1 << 3,
138	/* 1-host write data */
139	CMD_FLAG_DATA_OUT		= 1 << 4,
140
141	SCSI_CMD_MARVELL_SPECIFIC	= 0xE1,
142	CDB_CORE_SHUTDOWN		= 0xB,
143};
144
145#define APICDB0_EVENT			0xF4
146#define APICDB1_EVENT_GETEVENT		0
147#define MAX_EVENTS_RETURNED		6
148
149struct mvumi_driver_event {
150	u32	time_stamp;
151	u32	sequence_no;
152	u32	event_id;
153	u8	severity;
154	u8	param_count;
155	u16	device_id;
156	u32	params[4];
157	u8	sense_data_length;
158	u8	Reserved1;
159	u8	sense_data[30];
160};
161
162struct mvumi_event_req {
163	unsigned char	count;
164	unsigned char	reserved[3];
165	struct mvumi_driver_event  events[MAX_EVENTS_RETURNED];
166};
167
168struct mvumi_events_wq {
169	struct work_struct work_q;
170	struct mvumi_hba *mhba;
171	unsigned int event;
172	void *param;
173};
174
175#define MVUMI_MAX_SG_ENTRY	32
176#define SGD_EOT			(1L << 27)
177
178struct mvumi_sgl {
179	u32	baseaddr_l;
180	u32	baseaddr_h;
181	u32	flags;
182	u32	size;
183};
184
185struct mvumi_res {
186	struct list_head entry;
187	dma_addr_t bus_addr;
188	void *virt_addr;
189	unsigned int size;
190	unsigned short type;	/* enum Resource_Type */
191};
192
193/* Resource type */
194enum resource_type {
195	RESOURCE_CACHED_MEMORY = 0,
196	RESOURCE_UNCACHED_MEMORY
197};
198
199struct mvumi_sense_data {
200	u8 error_eode:7;
201	u8 valid:1;
202	u8 segment_number;
203	u8 sense_key:4;
204	u8 reserved:1;
205	u8 incorrect_length:1;
206	u8 end_of_media:1;
207	u8 file_mark:1;
208	u8 information[4];
209	u8 additional_sense_length;
210	u8 command_specific_information[4];
211	u8 additional_sense_code;
212	u8 additional_sense_code_qualifier;
213	u8 field_replaceable_unit_code;
214	u8 sense_key_specific[3];
215};
216
217/* Request initiator must set the status to REQ_STATUS_PENDING. */
218#define REQ_STATUS_PENDING		0x80
219
220struct mvumi_cmd {
221	struct list_head queue_pointer;
222	struct mvumi_msg_frame *frame;
223	struct scsi_cmnd *scmd;
224	atomic_t sync_cmd;
225	void *data_buf;
226	unsigned short request_id;
227	unsigned char cmd_status;
228};
229
230/*
231 * the function type of the in bound frame
232 */
233#define CL_FUN_SCSI_CMD			0x1
234
235struct mvumi_msg_frame {
236	u16 device_id;
237	u16 tag;
238	u8 cmd_flag;
239	u8 req_function;
240	u8 cdb_length;
241	u8 sg_counts;
242	u32 data_transfer_length;
243	u16 request_id;
244	u16 reserved1;
245	u8 cdb[MAX_COMMAND_SIZE];
246	u32 payload[1];
247};
248
249/*
250 * the respond flag for data_payload of the out bound frame
251 */
252#define CL_RSP_FLAG_NODATA		0x0
253#define CL_RSP_FLAG_SENSEDATA		0x1
254
255struct mvumi_rsp_frame {
256	u16 device_id;
257	u16 tag;
258	u8 req_status;
259	u8 rsp_flag;	/* Indicates the type of Data_Payload.*/
260	u16 request_id;
261	u32 payload[1];
262};
263
264struct mvumi_ob_data {
265	struct list_head list;
266	unsigned char data[0];
267};
268
269struct version_info {
270	u32 ver_major;
271	u32 ver_minor;
272	u32 ver_oem;
273	u32 ver_build;
274};
275
276#define FW_MAX_DELAY			30
277#define MVUMI_FW_BUSY			(1U << 0)
278#define MVUMI_FW_ATTACH			(1U << 1)
279#define MVUMI_FW_ALLOC			(1U << 2)
280
281/*
282 * State is the state of the MU
283 */
284#define FW_STATE_IDLE			0
285#define FW_STATE_STARTING		1
286#define FW_STATE_HANDSHAKING		2
287#define FW_STATE_STARTED		3
288#define FW_STATE_ABORT			4
289
290#define HANDSHAKE_SIGNATURE		0x5A5A5A5AL
291#define HANDSHAKE_READYSTATE		0x55AA5AA5L
292#define HANDSHAKE_DONESTATE		0x55AAA55AL
293
294/* HandShake Status definition */
295#define HS_STATUS_OK			1
296#define HS_STATUS_ERR			2
297#define HS_STATUS_INVALID		3
298
299/* HandShake State/Cmd definition */
300#define HS_S_START			1
301#define HS_S_RESET			2
302#define HS_S_PAGE_ADDR			3
303#define HS_S_QUERY_PAGE			4
304#define HS_S_SEND_PAGE			5
305#define HS_S_END			6
306#define HS_S_ABORT			7
307#define HS_PAGE_VERIFY_SIZE		128
308
309#define HS_GET_STATE(a)			(a & 0xFFFF)
310#define HS_GET_STATUS(a)		((a & 0xFFFF0000) >> 16)
311#define HS_SET_STATE(a, b)		(a |= (b & 0xFFFF))
312#define HS_SET_STATUS(a, b)		(a |= ((b & 0xFFFF) << 16))
313
314/* handshake frame */
315struct mvumi_hs_frame {
316	u16 size;
317	/* host information */
318	u8 host_type;
319	u8 reserved_1[1];
320	struct version_info host_ver; /* bios or driver version */
321
322	/* controller information */
323	u32 system_io_bus;
324	u32 slot_number;
325	u32 intr_level;
326	u32 intr_vector;
327
328	/* communication list configuration */
329	u32 ib_baseaddr_l;
330	u32 ib_baseaddr_h;
331	u32 ob_baseaddr_l;
332	u32 ob_baseaddr_h;
333
334	u8 ib_entry_size;
335	u8 ob_entry_size;
336	u8 ob_depth;
337	u8 ib_depth;
338
339	/* system time */
340	u64 seconds_since1970;
341};
342
343struct mvumi_hs_header {
344	u8	page_code;
345	u8	checksum;
346	u16	frame_length;
347	u32	frame_content[1];
348};
349
350/*
351 * the page code type of the handshake header
352 */
353#define HS_PAGE_FIRM_CAP	0x1
354#define HS_PAGE_HOST_INFO	0x2
355#define HS_PAGE_FIRM_CTL	0x3
356#define HS_PAGE_CL_INFO		0x4
357#define HS_PAGE_TOTAL		0x5
358
359#define HSP_SIZE(i)	sizeof(struct mvumi_hs_page##i)
360
361#define HSP_MAX_SIZE ({					\
362	int size, m1, m2;				\
363	m1 = max(HSP_SIZE(1), HSP_SIZE(3));		\
364	m2 = max(HSP_SIZE(2), HSP_SIZE(4));		\
365	size = max(m1, m2);				\
366	size;						\
367})
368
369/* The format of the page code for Firmware capability */
370struct mvumi_hs_page1 {
371	u8 pagecode;
372	u8 checksum;
373	u16 frame_length;
374
375	u16 number_of_ports;
376	u16 max_devices_support;
377	u16 max_io_support;
378	u16 umi_ver;
379	u32 max_transfer_size;
380	struct version_info fw_ver;
381	u8 cl_in_max_entry_size;
382	u8 cl_out_max_entry_size;
383	u8 cl_inout_list_depth;
384	u8 total_pages;
385	u16 capability;
386	u16 reserved1;
387};
388
389/* The format of the page code for Host information */
390struct mvumi_hs_page2 {
391	u8 pagecode;
392	u8 checksum;
393	u16 frame_length;
394
395	u8 host_type;
396	u8 reserved[3];
397	struct version_info host_ver;
398	u32 system_io_bus;
399	u32 slot_number;
400	u32 intr_level;
401	u32 intr_vector;
402	u64 seconds_since1970;
403};
404
405/* The format of the page code for firmware control  */
406struct mvumi_hs_page3 {
407	u8	pagecode;
408	u8	checksum;
409	u16	frame_length;
410	u16	control;
411	u8	reserved[2];
412	u32	host_bufferaddr_l;
413	u32	host_bufferaddr_h;
414	u32	host_eventaddr_l;
415	u32	host_eventaddr_h;
416};
417
418struct mvumi_hs_page4 {
419	u8	pagecode;
420	u8	checksum;
421	u16	frame_length;
422	u32	ib_baseaddr_l;
423	u32	ib_baseaddr_h;
424	u32	ob_baseaddr_l;
425	u32	ob_baseaddr_h;
426	u8	ib_entry_size;
427	u8	ob_entry_size;
428	u8	ob_depth;
429	u8	ib_depth;
430};
431
432struct mvumi_tag {
433	unsigned short *stack;
434	unsigned short top;
435	unsigned short size;
436};
437
438struct mvumi_hba {
439	void *base_addr[MAX_BASE_ADDRESS];
440	void *mmio;
441	struct list_head cmd_pool;
442	struct Scsi_Host *shost;
443	wait_queue_head_t int_cmd_wait_q;
444	struct pci_dev *pdev;
445	unsigned int unique_id;
446	atomic_t fw_outstanding;
447	struct mvumi_instance_template *instancet;
448
449	void *ib_list;
450	dma_addr_t ib_list_phys;
451
452	void *ob_list;
453	dma_addr_t ob_list_phys;
454
455	void *ib_shadow;
456	dma_addr_t ib_shadow_phys;
457
458	void *ob_shadow;
459	dma_addr_t ob_shadow_phys;
460
461	void *handshake_page;
462	dma_addr_t handshake_page_phys;
463
464	unsigned int global_isr;
465	unsigned int isr_status;
466
467	unsigned short max_sge;
468	unsigned short max_target_id;
469	unsigned char *target_map;
470	unsigned int max_io;
471	unsigned int list_num_io;
472	unsigned int ib_max_size;
473	unsigned int ob_max_size;
474	unsigned int ib_max_size_setting;
475	unsigned int ob_max_size_setting;
476	unsigned int max_transfer_size;
477	unsigned char hba_total_pages;
478	unsigned char fw_flag;
479	unsigned char request_id_enabled;
480	unsigned short hba_capability;
481	unsigned short io_seq;
482
483	unsigned int ib_cur_slot;
484	unsigned int ob_cur_slot;
485	unsigned int fw_state;
486
487	struct list_head ob_data_list;
488	struct list_head free_ob_list;
489	struct list_head res_list;
490	struct list_head waiting_req_list;
491
492	struct mvumi_tag tag_pool;
493	struct mvumi_cmd **tag_cmd;
494};
495
496struct mvumi_instance_template {
497	void (*fire_cmd)(struct mvumi_hba *, struct mvumi_cmd *);
498	void (*enable_intr)(void *) ;
499	void (*disable_intr)(void *);
500	int (*clear_intr)(void *);
501	unsigned int (*read_fw_status_reg)(void *);
502};
503
504extern struct timezone sys_tz;
505#endif
506