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