1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2009-2015 QLogic Corporation.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*
28  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
29  * Copyright 2009, 2015 Sun Microsystems, Inc.  All rights reserved.
30  * Use is subject to license terms.
31  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
32  */
33 
34 #ifndef	_QLT_H
35 #define	_QLT_H
36 
37 #include <sys/stmf_defines.h>
38 #include "qlt_regs.h"
39 
40 #ifdef	__cplusplus
41 extern "C" {
42 #endif
43 
44 /*
45  * Qlogic logging
46  */
47 extern int enable_extended_logging;
48 
49 /*
50  * Caution: 1) LOG will be available in debug/non-debug mode
51  *	    2) Anything which can potentially flood the log should be under
52  *	       extended logging, and use QLT_EXT_LOG.
53  *	    3) Don't use QLT_EXT_LOG in performance-critical code path, such
54  *	       as normal SCSI I/O code path. It could hurt system performance.
55  *	    4) Use kmdb to change enable_extened_logging in the fly to adjust
56  *	       tracing
57  */
58 #define	QLT_EXT_LOG(log_ident, ...)	\
59 		if (enable_extended_logging) {	\
60 			stmf_trace(log_ident, __VA_ARGS__);	\
61 		}
62 
63 #define	QLT_LOG(log_ident, ...)	\
64 	stmf_trace(log_ident, __VA_ARGS__)
65 
66 /*
67  * Error codes. FSC stands for Failure sub code.
68  */
69 #define	QLT_FAILURE			FCT_FCA_FAILURE
70 #define	QLT_SUCCESS			FCT_SUCCESS
71 #define	QLT_FSC(x)			((uint64_t)(x) << 40)
72 #define	QLT_DMA_STUCK			(QLT_FAILURE | QLT_FSC(1))
73 #define	QLT_MAILBOX_STUCK		(QLT_FAILURE | QLT_FSC(2))
74 #define	QLT_ROM_STUCK			(QLT_FAILURE | QLT_FSC(3))
75 #define	QLT_UNEXPECTED_RESPONSE		(QLT_FAILURE | QLT_FSC(4))
76 #define	QLT_MBOX_FAILED			(QLT_FAILURE | QLT_FSC(5))
77 #define	QLT_MBOX_NOT_INITIALIZED	(QLT_FAILURE | QLT_FSC(6))
78 #define	QLT_MBOX_BUSY			(QLT_FAILURE | QLT_FSC(7))
79 #define	QLT_MBOX_ABORTED		(QLT_FAILURE | QLT_FSC(8))
80 #define	QLT_MBOX_TIMEOUT		(QLT_FAILURE | QLT_FSC(9))
81 #define	QLT_RESP_TIMEOUT		(QLT_FAILURE | QLT_FSC(10))
82 #define	QLT_FLASH_TIMEOUT		(QLT_FAILURE | QLT_FSC(11))
83 #define	QLT_FLASH_ACCESS_ERROR		(QLT_FAILURE | QLT_FSC(12))
84 #define	QLT_BAD_NVRAM_DATA		(QLT_FAILURE | QLT_FSC(13))
85 #define	QLT_FIRMWARE_ERROR_CODE		(QLT_FAILURE | QLT_FSC(14))
86 
87 #define	QLT_FIRMWARE_ERROR(s, c1, c2)	(QLT_FIRMWARE_ERROR_CODE | \
88 	(((uint64_t)s) << 32) | (((uint64_t)c1) << 24) | ((uint64_t)c2))
89 
90 extern uint32_t fw2400_code01[];
91 extern uint32_t fw2400_length01;
92 extern uint32_t fw2400_addr01;
93 extern uint32_t fw2400_code02[];
94 extern uint32_t fw2400_length02;
95 extern uint32_t fw2400_addr02;
96 
97 extern uint32_t fw2500_code01[];
98 extern uint32_t fw2500_length01;
99 extern uint32_t fw2500_addr01;
100 extern uint32_t fw2500_code02[];
101 extern uint32_t fw2500_length02;
102 extern uint32_t fw2500_addr02;
103 
104 extern uint32_t fw2700_code01[];
105 extern uint32_t fw2700_length01;
106 extern uint32_t fw2700_addr01;
107 extern uint32_t fw2700_code02[];
108 extern uint32_t fw2700_length02;
109 extern uint32_t fw2700_addr02;
110 extern uint32_t	tmplt2700_code01[];
111 extern uint32_t	tmplt2700_length01;
112 
113 extern uint32_t fw8100_code01[];
114 extern uint32_t fw8100_length01;
115 extern uint32_t fw8100_addr01;
116 extern uint32_t fw8100_code02[];
117 extern uint32_t fw8100_length02;
118 extern uint32_t fw8100_addr02;
119 
120 extern uint32_t fw8300fc_code01[];
121 extern uint32_t fw8300fc_length01;
122 extern uint32_t fw8300fc_addr01;
123 extern uint32_t fw8300fc_code02[];
124 extern uint32_t fw8300fc_length02;
125 extern uint32_t fw8300fc_addr02;
126 
127 typedef enum {
128 	MBOX_STATE_UNKNOWN = 0,
129 	MBOX_STATE_READY,
130 	MBOX_STATE_CMD_RUNNING,
131 	MBOX_STATE_CMD_DONE
132 } mbox_state_t;
133 
134 /*
135  * ISP mailbox Self-Test status codes
136  */
137 #define	MBS_ROM_IDLE		0	/* Firmware Alive. */
138 #define	MBS_ROM_BUSY		4	/* Busy. */
139 #define	MBS_ROM_CONFIG_ERR	0xF	/* Board Config Error. */
140 #define	MBS_ROM_STATUS_MASK	0xF
141 
142 #define	MBS_FW_RUNNING		0x8400	/* firmware running. */
143 #define	MBS_FW_CONFIG_ERR	0x8401	/* firmware config error */
144 
145 /*
146  * ISP mailbox commands
147  */
148 #define	MBC_LOAD_RAM			0x01	/* Load RAM. */
149 #define	MBC_EXECUTE_FIRMWARE		0x02	/* Execute firmware. */
150 #define	MBC_DUMP_RAM			0x03	/* Dump RAM. */
151 #define	MBC_WRITE_RAM_WORD		0x04	/* Write RAM word. */
152 #define	MBC_READ_RAM_WORD		0x05	/* Read RAM word. */
153 #define	MBC_MPI_RAM			0x05	/* Load/dump MPI RAM. */
154 #define	MBC_MAILBOX_REGISTER_TEST	0x06	/* Wrap incoming mailboxes */
155 #define	MBC_VERIFY_CHECKSUM		0x07	/* Verify checksum. */
156 #define	MBC_ABOUT_FIRMWARE		0x08	/* About Firmware. */
157 #define	MBC_DUMP_RISC_RAM		0x0a	/* Dump RISC RAM command. */
158 #define	MBC_LOAD_RAM_EXTENDED		0x0b	/* Load RAM extended. */
159 #define	MBC_DUMP_RAM_EXTENDED		0x0c	/* Dump RAM extended. */
160 #define	MBC_WRITE_RAM_EXTENDED		0x0d	/* Write RAM word. */
161 #define	MBC_READ_RAM_EXTENDED		0x0f	/* Read RAM extended. */
162 #define	MBC_SERDES_TRANSMIT_PARAMETERS	0x10	/* Serdes Xmit Parameters */
163 #define	MBC_2300_EXECUTE_IOCB		0x12	/* ISP2300 Execute IOCB cmd */
164 #define	MBC_GET_IO_STATUS		0x12	/* ISP2422 Get I/O Status */
165 #define	MBC_STOP_FIRMWARE		0x14	/* Stop firmware */
166 #define	MBC_ABORT_COMMAND_IOCB		0x15	/* Abort IOCB command. */
167 #define	MBC_ABORT_DEVICE		0x16	/* Abort device (ID/LUN). */
168 #define	MBC_ABORT_TARGET		0x17	/* Abort target (ID). */
169 #define	MBC_RESET			0x18	/* Target reset. */
170 #define	MBC_XMIT_PARM			0x19	/* Change default xmit parms */
171 #define	MBC_PORT_PARAM			0x1a	/* Get/set port speed parms */
172 #define	MBC_INIT_MQ			0x1f	/* Initialize multiple queue */
173 #define	MBC_GET_ID			0x20	/* Get loop id of ISP2200. */
174 #define	MBC_GET_TIMEOUT_PARAMETERS	0x22	/* Get Timeout Parameters. */
175 #define	MBC_TRACE_CONTROL		0x27	/* Trace control. */
176 #define	MBC_GET_FIRMWARE_OPTIONS	0x28	/* Get firmware options */
177 #define	MBC_READ_SFP			0x31	/* Read SFP. */
178 
179 #define	MBC_SET_ADDITIONAL_FIRMWARE_OPT	0x38	/* set firmware options */
180 
181 #define	OPT_PUREX_ENABLE			(BIT_10)
182 
183 #define	MBC_RESET_MENLO			0x3a	/* Reset Menlo. */
184 #define	MBC_RESTART_MPI			0x3d	/* Restart MPI. */
185 #define	MBC_FLASH_ACCESS		0x3e	/* Flash Access Control */
186 #define	MBC_LOOP_PORT_BYPASS		0x40	/* Loop Port Bypass. */
187 #define	MBC_LOOP_PORT_ENABLE		0x41	/* Loop Port Enable. */
188 #define	MBC_GET_RESOURCE_COUNTS		0x42	/* Get Resource Counts. */
189 #define	MBC_NON_PARTICIPATE		0x43	/* Non-Participating Mode. */
190 #define	MBC_ECHO			0x44	/* ELS ECHO */
191 #define	MBC_DIAGNOSTIC_LOOP_BACK	0x45	/* Diagnostic loop back. */
192 #define	MBC_ONLINE_SELF_TEST		0x46	/* Online self-test. */
193 #define	MBC_ENHANCED_GET_PORT_DATABASE	0x47	/* Get Port Database + login */
194 #define	MBC_INITIALIZE_MULTI_ID_FW	0x48	/* Initialize multi-id fw */
195 #define	MBC_GET_DCBX_PARAMS		0x51	/* Get DCBX parameters */
196 #define	MBC_RESET_LINK_STATUS		0x52	/* Reset Link Error Status */
197 #define	MBC_EXECUTE_IOCB		0x54	/* 64 Bit Execute IOCB cmd. */
198 #define	MBC_SEND_RNID_ELS		0x57	/* Send RNID ELS request */
199 
200 #define	MBC_SET_PARAMETERS		0x59	/* Set parameters */
201 
202 #define	RNID_PARAMS_DF_FMT		0x00
203 #define	RNID_PARAMS_E0_FMT		0x01
204 #define	PUREX_ELS_CMDS			0x05
205 #define	FLOGI_PARAMS			0x06
206 
207 #define	PARAM_TYPE_FIELD_MASK		0xff
208 #define	PARAM_TYPE_FIELD_SHIFT		8
209 #define	PARAM_TYPE(type)		((type & PARAM_TYPE_FIELD_MASK) << \
210 					    PARAM_TYPE_FIELD_SHIFT)
211 
212 #define	MBC_GET_PARAMETERS		0x5a	/* Get RNID parameters */
213 #define	MBC_DATA_RATE			0x5d	/* Data Rate */
214 #define	MBC_INITIALIZE_FIRMWARE		0x60	/* Initialize firmware */
215 #define	MBC_INITIATE_LIP		0x62	/* Initiate LIP */
216 #define	MBC_GET_FC_AL_POSITION_MAP	0x63	/* Get FC_AL Position Map. */
217 #define	MBC_GET_PORT_DATABASE		0x64	/* Get Port Database. */
218 #define	MBC_CLEAR_ACA			0x65	/* Clear ACA. */
219 #define	MBC_TARGET_RESET		0x66	/* Target Reset. */
220 #define	MBC_CLEAR_TASK_SET		0x67	/* Clear Task Set. */
221 #define	MBC_ABORT_TASK_SET		0x68	/* Abort Task Set. */
222 #define	MBC_GET_FIRMWARE_STATE		0x69	/* Get firmware state. */
223 #define	MBC_GET_PORT_NAME		0x6a	/* Get port name. */
224 #define	MBC_GET_LINK_STATUS		0x6b	/* Get Link Status. */
225 #define	MBC_LIP_RESET			0x6c	/* LIP reset. */
226 #define	MBC_GET_STATUS_COUNTS		0x6d	/* Get Link Statistics and */
227 						/* Private Data Counts */
228 #define	MBC_SEND_SNS_COMMAND		0x6e	/* Send Simple Name Server */
229 #define	MBC_LOGIN_FABRIC_PORT		0x6f	/* Login fabric port. */
230 #define	MBC_SEND_CHANGE_REQUEST		0x70	/* Send Change Request. */
231 #define	MBC_LOGOUT_FABRIC_PORT		0x71	/* Logout fabric port. */
232 #define	MBC_LIP_FULL_LOGIN		0x72	/* Full login LIP. */
233 #define	MBC_LOGIN_LOOP_PORT		0x74	/* Login Loop Port. */
234 #define	MBC_PORT_NODE_NAME_LIST		0x75	/* Get port/node name list */
235 #define	MBC_INITIALIZE_IP		0x77	/* Initialize IP */
236 #define	MBC_SEND_FARP_REQ_COMMAND	0x78	/* FARP request. */
237 #define	MBC_UNLOAD_IP			0x79	/* Unload IP */
238 #define	MBC_GET_XGMAC_STATS		0x7a	/* Get XGMAC Statistics. */
239 #define	MBC_GET_ID_LIST			0x7c	/* Get port ID list. */
240 #define	MBC_SEND_LFA_COMMAND		0x7d	/* Send Loop Fabric Address */
241 #define	MBC_LUN_RESET			0x7e	/* Send Task mgmt LUN reset */
242 #define	MBC_IDC_REQUEST			0x100	/* IDC request */
243 #define	MBC_IDC_ACK			0x101	/* IDC acknowledge */
244 #define	MBC_IDC_TIME_EXTEND		0x102	/* IDC extend time */
245 #define	MBC_PORT_RESET			0x120	/* Port Reset */
246 #define	MBC_SET_PORT_CONFIG		0x122	/* Set port configuration */
247 #define	MBC_GET_PORT_CONFIG		0x123	/* Get port configuration */
248 
249 #define	IOCB_SIZE		64
250 
251 #define	MAX_SPEED_MASK	0x0000000F
252 #define	MAX_PORTS_MASK	0x000000F0
253 #define	MAX_SPEED_16G	0x0
254 #define	MAX_SPEED_32G	0x1
255 
256 /*
257  * These should not be constents but should be obtained from fw.
258  */
259 #define	QLT_MAX_LOGINS	2048
260 #define	QLT_MAX_XCHGES	2048
261 
262 #define	MAX_MBOXES	32
263 #define	MBOX_TIMEOUT	(14*1000*1000) /* for Palladium */
264 #define	DEREG_RP_TIMEOUT	(22*1000*1000)
265 
266 typedef struct {
267 	uint16_t	to_fw[MAX_MBOXES];
268 	uint32_t	to_fw_mask;
269 	uint16_t	from_fw[MAX_MBOXES];
270 	uint32_t	from_fw_mask;
271 	stmf_data_buf_t *dbuf;
272 } mbox_cmd_t;
273 
274 typedef struct qlt_abts_cmd {
275 	uint8_t		buf[IOCB_SIZE];
276 	uint16_t	qid;
277 } qlt_abts_cmd_t;
278 
279 struct qlt_dmem_bucket;
280 
281 #define	QLT_INTR_FIXED	0x1
282 #define	QLT_INTR_MSI	0x2
283 #define	QLT_INTR_MSIX	0x4
284 
285 #define	QL_LOG_ENTRIES	16384
286 #define	QL_LOG_LENGTH	128
287 
288 typedef struct qlt_trace_entry {
289 	timespec_t	hs_time;
290 	char		buf[QL_LOG_LENGTH];
291 } qlt_trace_entry_t;
292 
293 typedef struct qlt_trace_desc {
294 	kmutex_t	mutex;
295 	uint32_t	nentries;
296 	uint32_t	nindex;
297 	uint32_t	start;
298 	uint32_t	end;
299 	uint32_t	csize;
300 	uint32_t	count;
301 	size_t		trace_buffer_size;
302 	qlt_trace_entry_t	*trace_buffer;
303 } qlt_trace_desc_t;
304 
305 typedef struct qlt_mq_req_ptr_blk {
306 	kmutex_t	mq_lock;
307 	caddr_t		mq_ptr;
308 	uint32_t	mq_ndx_to_fw;
309 	uint32_t	mq_ndx_from_fw;
310 	uint32_t	mq_available;
311 
312 	ddi_dma_handle_t queue_mem_mq_dma_handle;
313 	ddi_acc_handle_t queue_mem_mq_acc_handle;
314 	caddr_t		 queue_mem_mq_base_addr;
315 	ddi_dma_cookie_t queue_mem_mq_cookie;
316 
317 } qlt_mq_req_ptr_blk_t;
318 
319 typedef struct qlt_mq_rsp_ptr_blk {
320 	kmutex_t	mq_lock;
321 	caddr_t		mq_ptr;
322 	uint32_t	mq_ndx_to_fw;
323 	uint32_t	mq_ndx_from_fw;
324 
325 	ddi_dma_handle_t queue_mem_mq_dma_handle;
326 	ddi_acc_handle_t queue_mem_mq_acc_handle;
327 	caddr_t		 queue_mem_mq_base_addr;
328 	ddi_dma_cookie_t queue_mem_mq_cookie;
329 
330 } qlt_mq_rsp_ptr_blk_t;
331 
332 typedef struct qlt_state {
333 	dev_info_t		*dip;
334 	char			qlt_minor_name[16];
335 	char			qlt_port_alias[16];
336 	fct_local_port_t	*qlt_port;
337 	struct qlt_dmem_bucket	**dmem_buckets;
338 
339 	struct qlt_dma_handle_pool
340 				*qlt_dma_handle_pool;
341 
342 
343 	int			instance;
344 	uint8_t			qlt_state:7,
345 				qlt_state_not_acked:1;
346 	uint8_t			qlt_intr_enabled:1,
347 				qlt_25xx_chip:1,
348 				qlt_stay_offline:1,
349 				qlt_link_up,
350 				qlt_81xx_chip:1,
351 				qlt_mq_enabled:1,
352 				qlt_83xx_chip:1,
353 				qlt_fcoe_enabled:1;
354 	uint8_t			qlt_27xx_chip:1,
355 				rsvd0:7;
356 	uint8_t			cur_topology;
357 
358 	/* Registers */
359 	caddr_t			regs;
360 	ddi_acc_handle_t	regs_acc_handle;
361 	ddi_acc_handle_t	pcicfg_acc_handle;
362 	caddr_t			msix_base;
363 	ddi_acc_handle_t	msix_acc_handle;
364 	caddr_t			mq_reg_base;
365 	ddi_acc_handle_t	mq_reg_acc_handle;
366 
367 	/* Interrupt stuff */
368 	kmutex_t		intr_lock;	/* Only used by intr routine */
369 	int			intr_sneak_counter;
370 	ddi_intr_handle_t	*htable;
371 	int			intr_size;
372 	int			intr_cnt;
373 	uint_t			intr_pri;
374 	int			intr_cap;
375 	int			intr_flags;
376 
377 	/* Queues */
378 	ddi_dma_handle_t queue_mem_dma_handle;
379 	ddi_acc_handle_t queue_mem_acc_handle;
380 	caddr_t		 queue_mem_ptr;
381 	ddi_dma_cookie_t queue_mem_cookie;
382 
383 /*
384  *	kmutex_t	req_lock;
385  *	caddr_t		req_ptr;
386  *	uint32_t	req_ndx_to_fw;
387  *	uint32_t	req_ndx_from_fw;
388  *	uint32_t	req_available;
389  */
390 
391 	qlt_mq_req_ptr_blk_t	*mq_req;
392 	qlt_mq_rsp_ptr_blk_t	*mq_resp;
393 /* MQMQ */
394 	uint32_t	qlt_queue_cnt;
395 	kmutex_t	qlock;
396 	uint32_t	last_qi;
397 
398 	kmutex_t	preq_lock;
399 	caddr_t		preq_ptr;
400 	uint32_t	preq_ndx_to_fw;
401 	uint32_t	preq_ndx_from_fw;
402 
403 	kcondvar_t	rp_dereg_cv; /* for deregister cmd */
404 	uint32_t	rp_id_in_dereg; /* remote port in deregistering */
405 	fct_status_t	rp_dereg_status;
406 
407 	caddr_t		atio_ptr;
408 	uint16_t	atio_ndx_to_fw;
409 	uint16_t	atio_ndx_from_fw;
410 
411 	kmutex_t	dma_mem_lock;
412 
413 	/* MailBox data */
414 	kmutex_t	mbox_lock;
415 	kcondvar_t	mbox_cv;
416 	mbox_state_t	mbox_io_state;
417 	mbox_cmd_t	*mcp;
418 	qlt_nvram_t	*nvram;
419 	uint32_t	*vpd;
420 	qlt_rom_image_t	rimage[6];
421 
422 	uint8_t		link_speed;	/* Cached from intr routine */
423 	uint16_t	fw_major;
424 	uint16_t	fw_minor;
425 	uint16_t	fw_subminor;
426 	uint16_t	fw_endaddrlo;
427 	uint16_t	fw_endaddrhi;
428 	uint16_t	fw_attr;
429 
430 	uint32_t	fw_addr01;
431 	uint32_t	fw_length01;
432 	uint32_t	*fw_code01;
433 	uint32_t	fw_addr02;
434 	uint32_t	fw_length02;
435 	uint32_t	*fw_code02;
436 
437 	uint32_t	fw_ext_memory_end;
438 	uint32_t	fw_shared_ram_start;
439 	uint32_t	fw_shared_ram_end;
440 	uint32_t	fw_ddr_ram_start;
441 	uint32_t	fw_ddr_ram_end;
442 
443 	uint32_t	qlt_ioctl_flags;
444 	kmutex_t	qlt_ioctl_lock;
445 	uint32_t	fw_dump_size;
446 	caddr_t		qlt_fwdump_buf;	/* FWDUMP will use ioctl flags/lock */
447 	uint32_t	qlt_change_state_flags;	/* Cached for ACK handling */
448 
449 	/* Dump template */
450 	ddi_dma_handle_t dmp_template_dma_handle;
451 	ddi_acc_handle_t dmp_template_acc_handle;
452 	caddr_t		 dmp_template_addr;
453 	ddi_dma_cookie_t dmp_template_cookie;
454 
455 	uint32_t	fw_bin_dump_size;
456 	caddr_t		fw_bin_dump_buf;
457 	uint32_t	fw_ascii_dump_size;
458 
459 	qlt_trace_desc_t *qlt_trace_desc;
460 	uint32_t	qlt_log_entries;
461 	uint8_t		qlt_eel_level;		/* extended error logging */
462 
463 	/* temp ref & stat counters */
464 	uint32_t	qlt_bucketcnt[5];	/* element 0 = 2k */
465 	uint64_t	qlt_bufref[5];		/* element 0 = 2k */
466 	uint64_t	qlt_bumpbucket;		/* bigger buffer supplied */
467 	uint64_t	qlt_pmintry;
468 	uint64_t	qlt_pmin_ok;
469 
470 	uint32_t	qlt_27xx_speed;
471 	uint32_t	qlt_atio_reproc_cnt;
472 	uint32_t	qlt_resp_reproc_cnt;
473 } qlt_state_t;
474 
475 /*
476  * FWDUMP flags (part of IOCTL flags)
477  */
478 #define	QLT_FWDUMP_INPROGRESS		0x0100	/* if it's dumping now */
479 #define	QLT_FWDUMP_TRIGGERED_BY_USER	0x0200	/* if users triggered it */
480 #define	QLT_FWDUMP_FETCHED_BY_USER	0x0400	/* if users have viewed it */
481 #define	QLT_FWDUMP_ISVALID		0x0800
482 
483 /*
484  * IOCTL supporting stuff
485  */
486 #define	QLT_IOCTL_FLAG_MASK		0xFF
487 #define	QLT_IOCTL_FLAG_IDLE		0x00
488 #define	QLT_IOCTL_FLAG_OPEN		0x01
489 #define	QLT_IOCTL_FLAG_EXCL		0x02
490 
491 typedef struct qlt_cmd {
492 	fct_cmd_t	*cmd;
493 	uint32_t	handle;
494 	stmf_data_buf_t	*dbuf;		/* dbuf with handle 0 for SCSI cmds */
495 	stmf_data_buf_t	*dbuf_rsp_iu;	/* dbuf for possible FCP_RSP IU */
496 	uint32_t	fw_xchg_addr;
497 	uint16_t	oxid;
498 	uint16_t	flags;
499 	union {
500 		uint16_t	resp_offset;
501 		uint8_t		atio_byte3;
502 	} param;
503 	uint16_t	qid;
504 } qlt_cmd_t;
505 
506 /*
507  * cmd flags
508  */
509 #define	QLT_CMD_ABORTING		1
510 #define	QLT_CMD_ABORTED			2
511 #define	QLT_CMD_TYPE_SOLICITED		4
512 
513 typedef struct {
514 	int	dummy;
515 } qlt_remote_port_t;
516 
517 #define	REQUEST_QUEUE_ENTRIES	2048
518 #define	RESPONSE_QUEUE_ENTRIES	2048
519 #define	ATIO_QUEUE_ENTRIES	2048
520 #define	PRIORITY_QUEUE_ENTRIES	128
521 
522 #define	REQUEST_QUEUE_OFFSET	0
523 #define	RESPONSE_QUEUE_OFFSET	(REQUEST_QUEUE_OFFSET + \
524 				    (REQUEST_QUEUE_ENTRIES * IOCB_SIZE))
525 #define	ATIO_QUEUE_OFFSET	(RESPONSE_QUEUE_OFFSET + \
526 				    (RESPONSE_QUEUE_ENTRIES * IOCB_SIZE))
527 #define	PRIORITY_QUEUE_OFFSET	(ATIO_QUEUE_OFFSET + \
528 				    (ATIO_QUEUE_ENTRIES * IOCB_SIZE))
529 #define	MBOX_DMA_MEM_SIZE	4096
530 #define	MBOX_DMA_MEM_OFFSET		(PRIORITY_QUEUE_OFFSET + \
531 				    (PRIORITY_QUEUE_ENTRIES * IOCB_SIZE))
532 #define	TOTAL_DMA_MEM_SIZE	(MBOX_DMA_MEM_OFFSET + MBOX_DMA_MEM_SIZE)
533 
534 #define	QLT_MAX_ITERATIONS_PER_INTR	32
535 
536 #define	REQUEST_QUEUE_MQ_ENTRIES	512
537 #define	REQUEST_QUEUE_MQ_SIZE	(REQUEST_QUEUE_MQ_ENTRIES * IOCB_SIZE)
538 
539 #define	RESPONSE_QUEUE_MQ_ENTRIES	512
540 #define	RESPONSE_QUEUE_MQ_SIZE	(RESPONSE_QUEUE_MQ_ENTRIES * IOCB_SIZE)
541 
542 #define	REG_RD8(qlt, addr) \
543 	ddi_get8(qlt->regs_acc_handle, (uint8_t *)(qlt->regs + addr))
544 #define	REG_RD16(qlt, addr) \
545 	ddi_get16(qlt->regs_acc_handle, (uint16_t *)(qlt->regs + addr))
546 #define	REG_RD32(qlt, addr) \
547 	ddi_get32(qlt->regs_acc_handle, (uint32_t *)(qlt->regs + addr))
548 #define	REG_WR16(qlt, addr, data) \
549 	ddi_put16(qlt->regs_acc_handle, (uint16_t *)(qlt->regs + addr), \
550 	(uint16_t)(data))
551 #define	REG_WR32(qlt, addr, data) \
552 	ddi_put32(qlt->regs_acc_handle, (uint32_t *)(qlt->regs + addr), \
553 	(uint32_t)(data))
554 
555 #define	PCICFG_RD8(qlt, addr) \
556 	pci_config_get8(qlt->pcicfg_acc_handle, (off_t)(addr))
557 #define	PCICFG_RD16(qlt, addr) \
558 	pci_config_get16(qlt->pcicfg_acc_handle, (off_t)(addr))
559 #define	PCICFG_RD32(qlt, addr) \
560 	pci_config_get32(qlt->pcicfg_acc_handle, (off_t)(addr))
561 #define	PCICFG_WR16(qlt, addr, data) \
562 	pci_config_put16(qlt->pcicfg_acc_handle, (off_t)(addr), \
563 	(uint16_t)(data))
564 #define	PCICFG_WR32(qlt, addr, data) \
565 	pci_config_put32(qlt->pcicfg_acc_handle, (off_t)(addr), \
566 	(uint32_t)(data))
567 
568 /*
569  * Used for Req/Resp queue 0 and atio queue only
570  */
571 #define	QMEM_RD16(qlt, addr) \
572 	ddi_get16(qlt->queue_mem_acc_handle, (uint16_t *)(addr))
573 #define	DMEM_RD16(qlt, addr) LE_16((uint16_t)(*((uint16_t *)(addr))))
574 #define	QMEM_RD32(qlt, addr) \
575 	ddi_get32(qlt->queue_mem_acc_handle, (uint32_t *)(addr))
576 #define	DMEM_RD32(qlt, addr) LE_32((uint32_t)(*((uint32_t *)(addr))))
577 
578 /*
579  * #define	QMEM_RD64(qlt, addr) \
580  *	ddi_get64(qlt->queue_mem_acc_handle, (uint64_t *)(addr))
581  */
582 #define	QMEM_WR16(qlt, addr, data) \
583 	ddi_put16(qlt->queue_mem_acc_handle, (uint16_t *)(addr), \
584 	(uint16_t)(data))
585 #define	DMEM_WR16(qlt, addr, data) (*((uint16_t *)(addr)) = \
586 	(uint16_t)LE_16((uint16_t)(data)))
587 #define	QMEM_WR32(qlt, addr, data) \
588 	ddi_put32(qlt->queue_mem_acc_handle, (uint32_t *)(addr), \
589 	(uint32_t)(data))
590 #define	DMEM_WR32(qlt, addr, data) (*((uint32_t *)(addr)) = \
591 	LE_32((uint32_t)(data)))
592 
593 /*
594  * [QD]MEM is always little endian so the [QD]MEM_WR64 macro works for
595  * both sparc and x86.
596  */
597 #define	QMEM_WR64(qlt, addr, data) \
598 	QMEM_WR32(qlt, addr, (data & 0xffffffff)), \
599 	QMEM_WR32(qlt, (addr)+4, ((uint64_t)data) >> 32)
600 
601 #define	DMEM_WR64(qlt, addr, data) \
602 	DMEM_WR32(qlt, addr, (data & 0xffffffff)), \
603 	DMEM_WR32(qlt, (addr)+4, ((uint64_t)data) >> 32)
604 
605 /*
606  * Multi Queue suppport since the queue access handles are
607  * allocated separetly.
608  */
609 #define	QMEM_RD16_REQ(qlt, qi, addr) \
610 	(qi == 0) ? QMEM_RD16(qlt, addr) : \
611 	ddi_get16(qlt->mq_req[qi].queue_mem_mq_acc_handle, \
612 	    (uint16_t *)(addr))
613 
614 #define	QMEM_RD16_RSPQ(qlt, qi, addr) \
615 	(qi == 0) ? QMEM_RD16(qlt, addr) : \
616 	ddi_get16(qlt->mq_resp[qi].queue_mem_mq_acc_handle, \
617 	    (uint16_t *)(addr))
618 
619 #define	QMEM_RD32_REQ(qlt, qi, addr) \
620 	(qi == 0) ? QMEM_RD32(qlt, addr) : \
621 	ddi_get32(qlt->mq_req[qi].queue_mem_mq_acc_handle, \
622 	    (uint32_t *)(addr))
623 
624 #define	QMEM_RD32_RSPQ(qlt, qi, addr) \
625 	(qi == 0) ? QMEM_RD32(qlt, addr) : \
626 	ddi_get32(qlt->mq_resp[qi].queue_mem_mq_acc_handle, \
627 	    (uint32_t *)(addr))
628 
629 #define	QMEM_WR16_REQ(qlt, qi, addr, data) \
630 	(qi == 0) ? QMEM_WR16(qlt, addr, data) : \
631 	ddi_put16(qlt->mq_req[qi].queue_mem_mq_acc_handle, \
632 	(uint16_t *)(addr), (uint16_t)(data))
633 
634 #define	QMEM_WR16_RSPQ(qlt, qi, addr, data) \
635 	(qi == 0) ? QMEM_WR16(qlt, addr, data) : \
636 	ddi_put16(qlt->mq_resp[qi].queue_mem_mq_acc_handle, \
637 	(uint16_t *)(addr), (uint16_t)(data))
638 
639 #define	QMEM_WR32_REQ(qlt, qi, addr, data) \
640 	(qi == 0) ? QMEM_WR32(qlt, addr, data) : \
641 	ddi_put32(qlt->mq_req[qi].queue_mem_mq_acc_handle, \
642 	(uint32_t *)(addr), (uint32_t)(data))
643 
644 #define	QMEM_WR32_RSPQ(qlt, qi, addr, data) \
645 	(qi == 0) ? QMEM_WR32(qlt, addr, data) : \
646 	ddi_put32(qlt->mq_resp[qi].queue_mem_mq_acc_handle, \
647 	(uint32_t *)(addr), (uint32_t)(data))
648 /*
649  * [QD]MEM is always little endian so the [QD]MEM_WR64 macro works for
650  * both sparc and x86.
651  */
652 #define	QMEM_WR64_REQ(qlt, qi, addr, data) \
653 	(qi == 0) ? QMEM_WR64(qlt, addr, data) : \
654 	QMEM_WR32_REQ(qlt, qi, addr, (data & 0xffffffff)), \
655 	QMEM_WR32_REQ(qlt, qi, (addr)+4, ((uint64_t)data) >> 32)
656 
657 #define	QMEM_WR64_RSPQ(qlt, qi, addr, data) \
658 	(qi == 0) ? QMEM_WR64(qlt, addr, data) : \
659 	QMEM_WR32_RSPQ(qlt, qi, addr, (data & 0xffffffff)), \
660 	QMEM_WR32_RSPQ(qlt, qi, (addr)+4, ((uint64_t)data) >> 32)
661 
662 /*
663  *	MBAR access for Multi-Queue
664  */
665 #define	MQBAR_RD16(qlt, addr) \
666 	ddi_get16(qlt->mq_reg_acc_handle, (uint16_t *)(qlt->mq_reg_base + addr))
667 
668 #define	MQBAR_RD32(qlt, addr) \
669 	ddi_get32(qlt->mq_reg_acc_handle, (uint32_t *)(qlt->mq_reg_base + addr))
670 
671 #define	MQBAR_WR16(qlt, addr, data) \
672 	ddi_put16(qlt->mq_reg_acc_handle, \
673 	(uint16_t *)(qlt->mq_reg_base + addr), \
674 	(uint16_t)(data))
675 
676 #define	MQBAR_WR32(qlt, addr, data) \
677 	ddi_put32(qlt->mq_reg_acc_handle, \
678 	(uint32_t *)(qlt->mq_reg_base + addr), \
679 	(uint32_t)(data))
680 
681 /*
682  * Structure used to associate values with strings which describe them.
683  */
684 typedef struct string_table_entry {
685 	uint32_t value;
686 	char    *string;
687 } string_table_t;
688 
689 char *prop_text(int prop_status);
690 char *value2string(string_table_t *entry, int value, int delimiter);
691 
692 #define	PROP_STATUS_DELIMITER	((uint32_t)0xFFFF)
693 
694 #define	DDI_PROP_STATUS()					\
695 {								\
696 	{DDI_PROP_SUCCESS, "DDI_PROP_SUCCESS"},			\
697 	{DDI_PROP_NOT_FOUND, "DDI_PROP_NOT_FOUND"},		\
698 	{DDI_PROP_UNDEFINED, "DDI_PROP_UNDEFINED"},		\
699 	{DDI_PROP_NO_MEMORY, "DDI_PROP_NO_MEMORY"},		\
700 	{DDI_PROP_INVAL_ARG, "DDI_PROP_INVAL_ARG"},		\
701 	{DDI_PROP_BUF_TOO_SMALL, "DDI_PROP_BUF_TOO_SMALL"},	\
702 	{DDI_PROP_CANNOT_DECODE, "DDI_PROP_CANNOT_DECODE"},	\
703 	{DDI_PROP_CANNOT_ENCODE, "DDI_PROP_CANNOT_ENCODE"},	\
704 	{DDI_PROP_END_OF_DATA, "DDI_PROP_END_OF_DATA"},		\
705 	{PROP_STATUS_DELIMITER, "DDI_PROP_UNKNOWN"}		\
706 }
707 
708 #ifndef TRUE
709 #define	TRUE	B_TRUE
710 #endif
711 
712 #ifndef FALSE
713 #define	FALSE	B_FALSE
714 #endif
715 
716 /* Little endian machine correction defines. */
717 #ifdef _LITTLE_ENDIAN
718 #define	LITTLE_ENDIAN_16(x)
719 #define	LITTLE_ENDIAN_24(x)
720 #define	LITTLE_ENDIAN_32(x)
721 #define	LITTLE_ENDIAN_64(x)
722 #define	LITTLE_ENDIAN(bp, bytes)
723 #define	BIG_ENDIAN_16(x)	qlt_chg_endian((uint8_t *)x, 2)
724 #define	BIG_ENDIAN_24(x)	qlt_chg_endian((uint8_t *)x, 3)
725 #define	BIG_ENDIAN_32(x)	qlt_chg_endian((uint8_t *)x, 4)
726 #define	BIG_ENDIAN_64(x)	qlt_chg_endian((uint8_t *)x, 8)
727 #define	BIG_ENDIAN(bp, bytes)	qlt_chg_endian((uint8_t *)bp, bytes)
728 #endif /* _LITTLE_ENDIAN */
729 
730 /* Big endian machine correction defines. */
731 #ifdef _BIG_ENDIAN
732 #define	LITTLE_ENDIAN_16(x)		qlt_chg_endian((uint8_t *)x, 2)
733 #define	LITTLE_ENDIAN_24(x)		qlt_chg_endian((uint8_t *)x, 3)
734 #define	LITTLE_ENDIAN_32(x)		qlt_chg_endian((uint8_t *)x, 4)
735 #define	LITTLE_ENDIAN_64(x)		qlt_chg_endian((uint8_t *)x, 8)
736 #define	LITTLE_ENDIAN(bp, bytes)	qlt_chg_endian((uint8_t *)bp, bytes)
737 #define	BIG_ENDIAN_16(x)
738 #define	BIG_ENDIAN_24(x)
739 #define	BIG_ENDIAN_32(x)
740 #define	BIG_ENDIAN_64(x)
741 #define	BIG_ENDIAN(bp, bytes)
742 #endif /* _BIG_ENDIAN */
743 
744 #define	LSB(x)		(uint8_t)(x)
745 #define	MSB(x)		(uint8_t)((uint16_t)(x) >> 8)
746 #define	MSW(x)		(uint16_t)((uint32_t)(x) >> 16)
747 #define	LSW(x)		(uint16_t)(x)
748 #define	LSD(x)		(uint32_t)(x)
749 #define	MSD(x)		(uint32_t)((uint64_t)(x) >> 32)
750 
751 #define	SHORT_TO_LONG(lsw, msw)	(uint32_t)((uint16_t)msw << 16 | (uint16_t)lsw)
752 #define	CHAR_TO_SHORT(lsb, msb)	(uint16_t)((uint8_t)msb << 8 | (uint8_t)lsb)
753 #define	CHAR_TO_LONG(lsb, b1, b2, msb) \
754 	(uint32_t)(SHORT_TO_LONG(CHAR_TO_SHORT(lsb, b1), \
755 	CHAR_TO_SHORT(b2, msb)))
756 
757 void	qlt_chg_endian(uint8_t *, size_t);
758 
759 #define	TRACE_BUFFER_LOCK(qlt)	mutex_enter(&qlt->qlt_trace_desc->mutex)
760 #define	TRACE_BUFFER_UNLOCK(qlt) mutex_exit(&qlt->qlt_trace_desc->mutex)
761 #define	QL_BANG	"!"
762 
763 void qlt_el_msg(qlt_state_t *qlt, const char *fn, int ce, ...);
764 void qlt_dump_el_trace_buffer(qlt_state_t *qlt);
765 #define	EL(qlt, ...) 	qlt_el_msg(qlt, __func__, CE_CONT, __VA_ARGS__);
766 #define	EL_TRACE_BUF_SIZE	8192
767 #define	EL_BUFFER_RESERVE	256
768 #define	DEBUG_STK_DEPTH		24
769 #define	EL_TRACE_BUF_SIZE	8192
770 
771 #ifdef	__cplusplus
772 }
773 #endif
774 
775 #endif /* _QLT_H */
776