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