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