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 
42 enum mvumi_qc_result {
43 	MV_QUEUE_COMMAND_RESULT_SENT	= 0,
44 	MV_QUEUE_COMMAND_RESULT_NO_RESOURCE,
45 };
46 
47 enum {
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 
149 struct 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 
162 struct mvumi_event_req {
163 	unsigned char	count;
164 	unsigned char	reserved[3];
165 	struct mvumi_driver_event  events[MAX_EVENTS_RETURNED];
166 };
167 
168 struct 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 
178 struct mvumi_sgl {
179 	u32	baseaddr_l;
180 	u32	baseaddr_h;
181 	u32	flags;
182 	u32	size;
183 };
184 
185 struct 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 */
194 enum resource_type {
195 	RESOURCE_CACHED_MEMORY = 0,
196 	RESOURCE_UNCACHED_MEMORY
197 };
198 
199 struct 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 
220 struct 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 
235 struct 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 
255 struct 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 
264 struct mvumi_ob_data {
265 	struct list_head list;
266 	unsigned char data[0];
267 };
268 
269 struct 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 */
315 struct 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 
343 struct 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 */
370 struct 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 */
390 struct 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  */
406 struct 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 
418 struct 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 
432 struct mvumi_tag {
433 	unsigned short *stack;
434 	unsigned short top;
435 	unsigned short size;
436 };
437 
438 struct 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 
496 struct 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 
504 extern struct timezone sys_tz;
505 #endif
506