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