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 QLogic Corporation. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 29 * Use is subject to license terms. 30 */ 31 32 #ifndef _QLT_H 33 #define _QLT_H 34 35 #include <stmf_defines.h> 36 #include <qlt_regs.h> 37 38 #ifdef __cplusplus 39 extern "C" { 40 #endif 41 42 /* 43 * Qlogic logging 44 */ 45 extern int enable_extended_logging; 46 47 /* 48 * Caution: 1) LOG will be available in debug/non-debug mode 49 * 2) Anything which can potentially flood the log should be under 50 * extended logging, and use QLT_EXT_LOG. 51 * 3) Don't use QLT_EXT_LOG in performance-critical code path, such 52 * as normal SCSI I/O code path. It could hurt system performance. 53 * 4) Use kmdb to change enable_extened_logging in the fly to adjust 54 * tracing 55 */ 56 #define QLT_EXT_LOG(log_ident, ...) \ 57 if (enable_extended_logging) { \ 58 stmf_trace(log_ident, __VA_ARGS__); \ 59 } 60 61 #define QLT_LOG(log_ident, ...) \ 62 stmf_trace(log_ident, __VA_ARGS__) 63 64 /* 65 * Error codes. FSC stands for Failure sub code. 66 */ 67 #define QLT_FAILURE FCT_FCA_FAILURE 68 #define QLT_SUCCESS FCT_SUCCESS 69 #define QLT_FSC(x) ((uint64_t)(x) << 40) 70 #define QLT_DMA_STUCK (QLT_FAILURE | QLT_FSC(1)) 71 #define QLT_MAILBOX_STUCK (QLT_FAILURE | QLT_FSC(2)) 72 #define QLT_ROM_STUCK (QLT_FAILURE | QLT_FSC(3)) 73 #define QLT_UNEXPECTED_RESPONSE (QLT_FAILURE | QLT_FSC(4)) 74 #define QLT_MBOX_FAILED (QLT_FAILURE | QLT_FSC(5)) 75 #define QLT_MBOX_NOT_INITIALIZED (QLT_FAILURE | QLT_FSC(6)) 76 #define QLT_MBOX_BUSY (QLT_FAILURE | QLT_FSC(7)) 77 #define QLT_MBOX_ABORTED (QLT_FAILURE | QLT_FSC(8)) 78 #define QLT_MBOX_TIMEOUT (QLT_FAILURE | QLT_FSC(9)) 79 #define QLT_RESP_TIMEOUT (QLT_FAILURE | QLT_FSC(10)) 80 #define QLT_FLASH_TIMEOUT (QLT_FAILURE | QLT_FSC(11)) 81 #define QLT_FLASH_ACCESS_ERROR (QLT_FAILURE | QLT_FSC(12)) 82 #define QLT_BAD_NVRAM_DATA (QLT_FAILURE | QLT_FSC(13)) 83 #define QLT_FIRMWARE_ERROR_CODE (QLT_FAILURE | QLT_FSC(14)) 84 85 #define QLT_FIRMWARE_ERROR(s, c1, c2) (QLT_FIRMWARE_ERROR_CODE | \ 86 (((uint64_t)s) << 32) | (((uint64_t)c1) << 24) | ((uint64_t)c2)) 87 88 extern uint32_t fw2400_code01[]; 89 extern uint32_t fw2400_length01; 90 extern uint32_t fw2400_addr01; 91 extern uint32_t fw2400_code02[]; 92 extern uint32_t fw2400_length02; 93 extern uint32_t fw2400_addr02; 94 95 extern uint32_t fw2500_code01[]; 96 extern uint32_t fw2500_length01; 97 extern uint32_t fw2500_addr01; 98 extern uint32_t fw2500_code02[]; 99 extern uint32_t fw2500_length02; 100 extern uint32_t fw2500_addr02; 101 102 extern uint32_t fw8100_code01[]; 103 extern uint32_t fw8100_length01; 104 extern uint32_t fw8100_addr01; 105 extern uint32_t fw8100_code02[]; 106 extern uint32_t fw8100_length02; 107 extern uint32_t fw8100_addr02; 108 109 typedef enum { 110 MBOX_STATE_UNKNOWN = 0, 111 MBOX_STATE_READY, 112 MBOX_STATE_CMD_RUNNING, 113 MBOX_STATE_CMD_DONE 114 } mbox_state_t; 115 116 #define IOCB_SIZE 64 117 118 /* 119 * These should not be constents but should be obtained from fw. 120 */ 121 #define QLT_MAX_LOGINS 2048 122 #define QLT_MAX_XCHGES 2048 123 124 #define MAX_MBOXES 32 125 #define MBOX_TIMEOUT (2*1000*1000) 126 #define DEREG_RP_TIMEOUT (2*1000*1000) 127 128 typedef struct { 129 uint16_t to_fw[MAX_MBOXES]; 130 uint32_t to_fw_mask; 131 uint16_t from_fw[MAX_MBOXES]; 132 uint32_t from_fw_mask; 133 stmf_data_buf_t *dbuf; 134 } mbox_cmd_t; 135 136 typedef struct qlt_abts_cmd { 137 uint8_t buf[IOCB_SIZE]; 138 } qlt_abts_cmd_t; 139 140 struct qlt_dmem_bucket; 141 142 #define QLT_INTR_FIXED 0x1 143 #define QLT_INTR_MSI 0x2 144 #define QLT_INTR_MSIX 0x4 145 146 typedef struct qlt_el_trace_desc { 147 kmutex_t mutex; 148 uint16_t next; 149 uint32_t trace_buffer_size; 150 char *trace_buffer; 151 } qlt_el_trace_desc_t; 152 153 typedef struct qlt_state { 154 dev_info_t *dip; 155 char qlt_minor_name[16]; 156 char qlt_port_alias[16]; 157 fct_local_port_t *qlt_port; 158 struct qlt_dmem_bucket **dmem_buckets; 159 160 int instance; 161 uint8_t qlt_state:7, 162 qlt_state_not_acked:1; 163 uint8_t qlt_intr_enabled:1, 164 qlt_25xx_chip:1, 165 qlt_stay_offline:1, 166 qlt_link_up, 167 qlt_81xx_chip:1, 168 qlt_rsvd1:3; 169 uint8_t cur_topology; 170 171 /* Registers */ 172 caddr_t regs; 173 ddi_acc_handle_t regs_acc_handle; 174 ddi_acc_handle_t pcicfg_acc_handle; 175 176 /* Interrupt stuff */ 177 kmutex_t intr_lock; /* Only used by intr routine */ 178 int intr_sneak_counter; 179 ddi_intr_handle_t *htable; 180 int intr_size; 181 int intr_cnt; 182 uint_t intr_pri; 183 int intr_cap; 184 int intr_flags; 185 186 /* Queues */ 187 ddi_dma_handle_t queue_mem_dma_handle; 188 ddi_acc_handle_t queue_mem_acc_handle; 189 caddr_t queue_mem_ptr; 190 ddi_dma_cookie_t queue_mem_cookie; 191 192 kmutex_t req_lock; 193 caddr_t req_ptr; 194 uint32_t req_ndx_to_fw; 195 uint32_t req_ndx_from_fw; 196 uint32_t req_available; 197 198 caddr_t resp_ptr; 199 uint32_t resp_ndx_to_fw; 200 uint32_t resp_ndx_from_fw; 201 202 kmutex_t preq_lock; 203 caddr_t preq_ptr; 204 uint32_t preq_ndx_to_fw; 205 uint32_t preq_ndx_from_fw; 206 207 kcondvar_t rp_dereg_cv; /* for deregister cmd */ 208 uint32_t rp_id_in_dereg; /* remote port in deregistering */ 209 fct_status_t rp_dereg_status; 210 211 caddr_t atio_ptr; 212 uint16_t atio_ndx_to_fw; 213 uint16_t atio_ndx_from_fw; 214 215 kmutex_t dma_mem_lock; 216 217 /* MailBox data */ 218 kmutex_t mbox_lock; 219 kcondvar_t mbox_cv; 220 mbox_state_t mbox_io_state; 221 mbox_cmd_t *mcp; 222 qlt_nvram_t *nvram; 223 224 uint8_t link_speed; /* Cached from intr routine */ 225 uint16_t fw_major; 226 uint16_t fw_minor; 227 uint16_t fw_subminor; 228 uint16_t fw_endaddrlo; 229 uint16_t fw_endaddrhi; 230 uint16_t fw_attr; 231 232 uint32_t fw_addr01; 233 uint32_t fw_length01; 234 uint32_t *fw_code01; 235 uint32_t fw_addr02; 236 uint32_t fw_length02; 237 uint32_t *fw_code02; 238 239 uint32_t qlt_ioctl_flags; 240 kmutex_t qlt_ioctl_lock; 241 caddr_t qlt_fwdump_buf; /* FWDUMP will use ioctl flags/lock */ 242 uint32_t qlt_change_state_flags; /* Cached for ACK handling */ 243 244 qlt_el_trace_desc_t *el_trace_desc; 245 } qlt_state_t; 246 247 /* 248 * FWDUMP flags (part of IOCTL flags) 249 */ 250 #define QLT_FWDUMP_INPROGRESS 0x0100 /* if it's dumping now */ 251 #define QLT_FWDUMP_TRIGGERED_BY_USER 0x0200 /* if users triggered it */ 252 #define QLT_FWDUMP_FETCHED_BY_USER 0x0400 /* if users have viewed it */ 253 #define QLT_FWDUMP_ISVALID 0x0800 254 255 /* 256 * IOCTL supporting stuff 257 */ 258 #define QLT_IOCTL_FLAG_MASK 0xFF 259 #define QLT_IOCTL_FLAG_IDLE 0x00 260 #define QLT_IOCTL_FLAG_OPEN 0x01 261 #define QLT_IOCTL_FLAG_EXCL 0x02 262 263 typedef struct qlt_cmd { 264 stmf_data_buf_t *dbuf; /* dbuf with handle 0 for SCSI cmds */ 265 stmf_data_buf_t *dbuf_rsp_iu; /* dbuf for possible FCP_RSP IU */ 266 uint32_t fw_xchg_addr; 267 uint16_t flags; 268 union { 269 uint16_t resp_offset; 270 uint8_t atio_byte3; 271 } param; 272 } qlt_cmd_t; 273 274 /* 275 * cmd flags 276 */ 277 #define QLT_CMD_ABORTING 1 278 #define QLT_CMD_ABORTED 2 279 #define QLT_CMD_TYPE_SOLICITED 4 280 281 typedef struct { 282 int dummy; 283 } qlt_remote_port_t; 284 285 #define REQUEST_QUEUE_ENTRIES 2048 286 #define RESPONSE_QUEUE_ENTRIES 2048 287 #define ATIO_QUEUE_ENTRIES 2048 288 #define PRIORITY_QUEUE_ENTRIES 128 289 290 #define REQUEST_QUEUE_OFFSET 0 291 #define RESPONSE_QUEUE_OFFSET (REQUEST_QUEUE_OFFSET + \ 292 (REQUEST_QUEUE_ENTRIES * IOCB_SIZE)) 293 #define ATIO_QUEUE_OFFSET (RESPONSE_QUEUE_OFFSET + \ 294 (RESPONSE_QUEUE_ENTRIES * IOCB_SIZE)) 295 #define PRIORITY_QUEUE_OFFSET (ATIO_QUEUE_OFFSET + \ 296 (ATIO_QUEUE_ENTRIES * IOCB_SIZE)) 297 #define MBOX_DMA_MEM_SIZE 4096 298 #define MBOX_DMA_MEM_OFFSET (PRIORITY_QUEUE_OFFSET + \ 299 (PRIORITY_QUEUE_ENTRIES * IOCB_SIZE)) 300 #define TOTAL_DMA_MEM_SIZE (MBOX_DMA_MEM_OFFSET + MBOX_DMA_MEM_SIZE) 301 302 #define QLT_MAX_ITERATIONS_PER_INTR 32 303 304 #define REG_RD16(qlt, addr) \ 305 ddi_get16(qlt->regs_acc_handle, (uint16_t *)(qlt->regs + addr)) 306 #define REG_RD32(qlt, addr) \ 307 ddi_get32(qlt->regs_acc_handle, (uint32_t *)(qlt->regs + addr)) 308 #define REG_WR16(qlt, addr, data) \ 309 ddi_put16(qlt->regs_acc_handle, (uint16_t *)(qlt->regs + addr), \ 310 (uint16_t)(data)) 311 #define REG_WR32(qlt, addr, data) \ 312 ddi_put32(qlt->regs_acc_handle, (uint32_t *)(qlt->regs + addr), \ 313 (uint32_t)(data)) 314 #define PCICFG_RD16(qlt, addr) \ 315 pci_config_get16(qlt->pcicfg_acc_handle, (off_t)(addr)) 316 #define PCICFG_RD32(qlt, addr) \ 317 pci_config_get32(qlt->pcicfg_acc_handle, (off_t)(addr)) 318 #define PCICFG_WR16(qlt, addr, data) \ 319 pci_config_put16(qlt->pcicfg_acc_handle, (off_t)(addr), \ 320 (uint16_t)(data)) 321 #define QMEM_RD16(qlt, addr) \ 322 ddi_get16(qlt->queue_mem_acc_handle, (uint16_t *)(addr)) 323 #define DMEM_RD16(qlt, addr) LE_16((uint16_t)(*((uint16_t *)(addr)))) 324 #define QMEM_RD32(qlt, addr) \ 325 ddi_get32(qlt->queue_mem_acc_handle, (uint32_t *)(addr)) 326 #define DMEM_RD32(qlt, addr) LE_32((uint32_t)(*((uint32_t *)(addr)))) 327 /* 328 * #define QMEM_RD64(qlt, addr) \ 329 * ddi_get64(qlt->queue_mem_acc_handle, (uint64_t *)(addr)) 330 */ 331 #define QMEM_WR16(qlt, addr, data) \ 332 ddi_put16(qlt->queue_mem_acc_handle, (uint16_t *)(addr), \ 333 (uint16_t)(data)) 334 #define DMEM_WR16(qlt, addr, data) (*((uint16_t *)(addr)) = \ 335 (uint16_t)LE_16((uint16_t)(data))) 336 #define QMEM_WR32(qlt, addr, data) \ 337 ddi_put32(qlt->queue_mem_acc_handle, (uint32_t *)(addr), \ 338 (uint32_t)(data)) 339 #define DMEM_WR32(qlt, addr, data) (*((uint32_t *)(addr)) = \ 340 LE_32((uint32_t)(data))) 341 342 /* 343 * [QD]MEM is always little endian so the [QD]MEM_WR64 macro works for 344 * both sparc and x86. 345 */ 346 #define QMEM_WR64(qlt, addr, data) \ 347 QMEM_WR32(qlt, addr, (data & 0xffffffff)), \ 348 QMEM_WR32(qlt, (addr)+4, ((uint64_t)data) >> 32) 349 350 #define DMEM_WR64(qlt, addr, data) \ 351 DMEM_WR32(qlt, addr, (data & 0xffffffff)), \ 352 DMEM_WR32(qlt, (addr)+4, ((uint64_t)data) >> 32) 353 354 /* 355 * Structure used to associate values with strings which describe them. 356 */ 357 typedef struct string_table_entry { 358 uint32_t value; 359 char *string; 360 } string_table_t; 361 362 char *prop_text(int prop_status); 363 char *value2string(string_table_t *entry, int value, int delimiter); 364 365 #define PROP_STATUS_DELIMITER ((uint32_t)0xFFFF) 366 367 #define DDI_PROP_STATUS() \ 368 { \ 369 {DDI_PROP_SUCCESS, "DDI_PROP_SUCCESS"}, \ 370 {DDI_PROP_NOT_FOUND, "DDI_PROP_NOT_FOUND"}, \ 371 {DDI_PROP_UNDEFINED, "DDI_PROP_UNDEFINED"}, \ 372 {DDI_PROP_NO_MEMORY, "DDI_PROP_NO_MEMORY"}, \ 373 {DDI_PROP_INVAL_ARG, "DDI_PROP_INVAL_ARG"}, \ 374 {DDI_PROP_BUF_TOO_SMALL, "DDI_PROP_BUF_TOO_SMALL"}, \ 375 {DDI_PROP_CANNOT_DECODE, "DDI_PROP_CANNOT_DECODE"}, \ 376 {DDI_PROP_CANNOT_ENCODE, "DDI_PROP_CANNOT_ENCODE"}, \ 377 {DDI_PROP_END_OF_DATA, "DDI_PROP_END_OF_DATA"}, \ 378 {PROP_STATUS_DELIMITER, "DDI_PROP_UNKNOWN"} \ 379 } 380 381 #ifndef TRUE 382 #define TRUE B_TRUE 383 #endif 384 385 #ifndef FALSE 386 #define FALSE B_FALSE 387 #endif 388 389 /* Little endian machine correction defines. */ 390 #ifdef _LITTLE_ENDIAN 391 #define LITTLE_ENDIAN_16(x) 392 #define LITTLE_ENDIAN_24(x) 393 #define LITTLE_ENDIAN_32(x) 394 #define LITTLE_ENDIAN_64(x) 395 #define LITTLE_ENDIAN(bp, bytes) 396 #define BIG_ENDIAN_16(x) qlt_chg_endian((uint8_t *)x, 2) 397 #define BIG_ENDIAN_24(x) qlt_chg_endian((uint8_t *)x, 3) 398 #define BIG_ENDIAN_32(x) qlt_chg_endian((uint8_t *)x, 4) 399 #define BIG_ENDIAN_64(x) qlt_chg_endian((uint8_t *)x, 8) 400 #define BIG_ENDIAN(bp, bytes) qlt_chg_endian((uint8_t *)bp, bytes) 401 #endif /* _LITTLE_ENDIAN */ 402 403 /* Big endian machine correction defines. */ 404 #ifdef _BIG_ENDIAN 405 #define LITTLE_ENDIAN_16(x) qlt_chg_endian((uint8_t *)x, 2) 406 #define LITTLE_ENDIAN_24(x) qlt_chg_endian((uint8_t *)x, 3) 407 #define LITTLE_ENDIAN_32(x) qlt_chg_endian((uint8_t *)x, 4) 408 #define LITTLE_ENDIAN_64(x) qlt_chg_endian((uint8_t *)x, 8) 409 #define LITTLE_ENDIAN(bp, bytes) qlt_chg_endian((uint8_t *)bp, bytes) 410 #define BIG_ENDIAN_16(x) 411 #define BIG_ENDIAN_24(x) 412 #define BIG_ENDIAN_32(x) 413 #define BIG_ENDIAN_64(x) 414 #define BIG_ENDIAN(bp, bytes) 415 #endif /* _BIG_ENDIAN */ 416 417 void qlt_chg_endian(uint8_t *, size_t); 418 419 void qlt_el_msg(qlt_state_t *qlt, const char *fn, int ce, ...); 420 void qlt_dump_el_trace_buffer(qlt_state_t *qlt); 421 #define EL(qlt, ...) qlt_el_msg(qlt, __func__, CE_CONT, __VA_ARGS__); 422 #define EL_TRACE_BUF_SIZE 8192 423 #define EL_BUFFER_RESERVE 256 424 #define DEBUG_STK_DEPTH 24 425 #define EL_TRACE_BUF_SIZE 8192 426 427 #ifdef __cplusplus 428 } 429 #endif 430 431 #endif /* _QLT_H */ 432