qlt.h revision 10733:b95259752377
1234285Sdim/* 2234285Sdim * CDDL HEADER START 3234285Sdim * 4234285Sdim * The contents of this file are subject to the terms of the 5234285Sdim * Common Development and Distribution License (the "License"). 6234285Sdim * You may not use this file except in compliance with the License. 7234285Sdim * 8234285Sdim * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9234285Sdim * or http://www.opensolaris.org/os/licensing. 10234285Sdim * See the License for the specific language governing permissions 11234285Sdim * and limitations under the License. 12234285Sdim * 13234285Sdim * When distributing Covered Code, include this CDDL HEADER in each 14234285Sdim * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15234285Sdim * If applicable, add the following below this CDDL HEADER, with the 16234285Sdim * fields enclosed by brackets "[]" replaced with your own identifying 17239462Sdim * information: Portions Copyright [yyyy] [name of copyright owner] 18234285Sdim * 19234285Sdim * CDDL HEADER END 20234285Sdim */ 21234285Sdim 22234285Sdim/* 23234285Sdim * Copyright 2009 QLogic Corporation. All rights reserved. 24234285Sdim * Use is subject to license terms. 25234285Sdim */ 26234285Sdim 27234285Sdim/* 28234285Sdim * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 29234285Sdim * Use is subject to license terms. 30249423Sdim */ 31249423Sdim 32249423Sdim#ifndef _QLT_H 33234285Sdim#define _QLT_H 34234285Sdim 35234285Sdim#include <stmf_defines.h> 36234285Sdim#include <qlt_regs.h> 37234285Sdim 38234285Sdim#ifdef __cplusplus 39234285Sdimextern "C" { 40249423Sdim#endif 41234285Sdim 42234285Sdim/* 43249423Sdim * Qlogic logging 44249423Sdim */ 45249423Sdimextern int enable_extended_logging; 46234285Sdim 47234285Sdim/* 48234285Sdim * Caution: 1) LOG will be available in debug/non-debug mode 49234285Sdim * 2) Anything which can potentially flood the log should be under 50234285Sdim * extended logging, and use QLT_EXT_LOG. 51234285Sdim * 3) Don't use QLT_EXT_LOG in performance-critical code path, such 52251662Sdim * as normal SCSI I/O code path. It could hurt system performance. 53251662Sdim * 4) Use kmdb to change enable_extened_logging in the fly to adjust 54251662Sdim * tracing 55251662Sdim */ 56251662Sdim#define QLT_EXT_LOG(log_ident, ...) \ 57234285Sdim if (enable_extended_logging) { \ 58234285Sdim stmf_trace(log_ident, __VA_ARGS__); \ 59234285Sdim } 60251662Sdim 61234285Sdim#define QLT_LOG(log_ident, ...) \ 62234285Sdim stmf_trace(log_ident, __VA_ARGS__) 63234285Sdim 64234285Sdim/* 65251662Sdim * Error codes. FSC stands for Failure sub code. 66251662Sdim */ 67251662Sdim#define QLT_FAILURE FCT_FCA_FAILURE 68251662Sdim#define QLT_SUCCESS FCT_SUCCESS 69234285Sdim#define QLT_FSC(x) ((uint64_t)(x) << 40) 70234285Sdim#define QLT_DMA_STUCK (QLT_FAILURE | QLT_FSC(1)) 71234285Sdim#define QLT_MAILBOX_STUCK (QLT_FAILURE | QLT_FSC(2)) 72234285Sdim#define QLT_ROM_STUCK (QLT_FAILURE | QLT_FSC(3)) 73234285Sdim#define QLT_UNEXPECTED_RESPONSE (QLT_FAILURE | QLT_FSC(4)) 74234285Sdim#define QLT_MBOX_FAILED (QLT_FAILURE | QLT_FSC(5)) 75234285Sdim#define QLT_MBOX_NOT_INITIALIZED (QLT_FAILURE | QLT_FSC(6)) 76234285Sdim#define QLT_MBOX_BUSY (QLT_FAILURE | QLT_FSC(7)) 77234285Sdim#define QLT_MBOX_ABORTED (QLT_FAILURE | QLT_FSC(8)) 78234285Sdim#define QLT_MBOX_TIMEOUT (QLT_FAILURE | QLT_FSC(9)) 79234285Sdim#define QLT_RESP_TIMEOUT (QLT_FAILURE | QLT_FSC(10)) 80234285Sdim#define QLT_FLASH_TIMEOUT (QLT_FAILURE | QLT_FSC(11)) 81234285Sdim#define QLT_FLASH_ACCESS_ERROR (QLT_FAILURE | QLT_FSC(12)) 82234285Sdim#define QLT_BAD_NVRAM_DATA (QLT_FAILURE | QLT_FSC(13)) 83234285Sdim#define QLT_FIRMWARE_ERROR_CODE (QLT_FAILURE | QLT_FSC(14)) 84234285Sdim 85234285Sdim#define QLT_FIRMWARE_ERROR(s, c1, c2) (QLT_FIRMWARE_ERROR_CODE | \ 86234285Sdim (((uint64_t)s) << 32) | (((uint64_t)c1) << 24) | ((uint64_t)c2)) 87234285Sdim 88234285Sdimextern uint32_t fw2400_code01[]; 89234285Sdimextern uint32_t fw2400_length01; 90234285Sdimextern uint32_t fw2400_addr01; 91234285Sdimextern uint32_t fw2400_code02[]; 92239462Sdimextern uint32_t fw2400_length02; 93239462Sdimextern uint32_t fw2400_addr02; 94239462Sdim 95239462Sdimextern uint32_t fw2500_code01[]; 96239462Sdimextern uint32_t fw2500_length01; 97239462Sdimextern uint32_t fw2500_addr01; 98239462Sdimextern uint32_t fw2500_code02[]; 99239462Sdimextern uint32_t fw2500_length02; 100234285Sdimextern uint32_t fw2500_addr02; 101239462Sdim 102239462Sdimextern uint32_t fw8100_code01[]; 103239462Sdimextern uint32_t fw8100_length01; 104239462Sdimextern uint32_t fw8100_addr01; 105239462Sdimextern uint32_t fw8100_code02[]; 106239462Sdimextern uint32_t fw8100_length02; 107239462Sdimextern uint32_t fw8100_addr02; 108239462Sdim 109239462Sdimtypedef enum { 110234285Sdim MBOX_STATE_UNKNOWN = 0, 111239462Sdim MBOX_STATE_READY, 112239462Sdim MBOX_STATE_CMD_RUNNING, 113239462Sdim MBOX_STATE_CMD_DONE 114239462Sdim} mbox_state_t; 115239462Sdim 116239462Sdim#define IOCB_SIZE 64 117239462Sdim 118239462Sdim/* 119239462Sdim * These should not be constents but should be obtained from fw. 120239462Sdim */ 121239462Sdim#define QLT_MAX_LOGINS 2048 122239462Sdim#define QLT_MAX_XCHGES 2048 123239462Sdim 124234285Sdim#define MAX_MBOXES 32 125239462Sdim#define MBOX_TIMEOUT (2*1000*1000) 126239462Sdim#define DEREG_RP_TIMEOUT (2*1000*1000) 127239462Sdim 128239462Sdimtypedef struct { 129239462Sdim uint16_t to_fw[MAX_MBOXES]; 130239462Sdim uint32_t to_fw_mask; 131239462Sdim uint16_t from_fw[MAX_MBOXES]; 132239462Sdim uint32_t from_fw_mask; 133239462Sdim stmf_data_buf_t *dbuf; 134239462Sdim} mbox_cmd_t; 135239462Sdim 136239462Sdimtypedef struct qlt_abts_cmd { 137239462Sdim uint8_t buf[IOCB_SIZE]; 138239462Sdim} qlt_abts_cmd_t; 139239462Sdim 140239462Sdimstruct qlt_dmem_bucket; 141239462Sdim 142239462Sdim#define QLT_INTR_FIXED 0x1 143239462Sdim#define QLT_INTR_MSI 0x2 144239462Sdim#define QLT_INTR_MSIX 0x4 145239462Sdim 146239462Sdimtypedef struct qlt_el_trace_desc { 147239462Sdim kmutex_t mutex; 148239462Sdim uint16_t next; 149239462Sdim uint32_t trace_buffer_size; 150239462Sdim char *trace_buffer; 151239462Sdim} qlt_el_trace_desc_t; 152234285Sdim 153239462Sdimtypedef struct qlt_state { 154239462Sdim dev_info_t *dip; 155239462Sdim char qlt_minor_name[16]; 156239462Sdim char qlt_port_alias[16]; 157239462Sdim fct_local_port_t *qlt_port; 158239462Sdim struct qlt_dmem_bucket **dmem_buckets; 159239462Sdim 160239462Sdim int instance; 161239462Sdim uint8_t qlt_state:7, 162239462Sdim qlt_state_not_acked:1; 163239462Sdim uint8_t qlt_intr_enabled:1, 164239462Sdim qlt_25xx_chip:1, 165239462Sdim qlt_stay_offline:1, 166239462Sdim qlt_link_up, 167239462Sdim qlt_81xx_chip:1, 168239462Sdim qlt_rsvd1:3; 169239462Sdim uint8_t cur_topology; 170239462Sdim 171239462Sdim /* Registers */ 172239462Sdim caddr_t regs; 173239462Sdim ddi_acc_handle_t regs_acc_handle; 174239462Sdim ddi_acc_handle_t pcicfg_acc_handle; 175239462Sdim 176239462Sdim /* Interrupt stuff */ 177239462Sdim kmutex_t intr_lock; /* Only used by intr routine */ 178239462Sdim int intr_sneak_counter; 179239462Sdim ddi_intr_handle_t *htable; 180239462Sdim int intr_size; 181239462Sdim int intr_cnt; 182239462Sdim uint_t intr_pri; 183239462Sdim int intr_cap; 184239462Sdim int intr_flags; 185239462Sdim 186239462Sdim /* Queues */ 187239462Sdim ddi_dma_handle_t queue_mem_dma_handle; 188239462Sdim ddi_acc_handle_t queue_mem_acc_handle; 189239462Sdim caddr_t queue_mem_ptr; 190239462Sdim ddi_dma_cookie_t queue_mem_cookie; 191239462Sdim 192239462Sdim kmutex_t req_lock; 193239462Sdim caddr_t req_ptr; 194239462Sdim uint32_t req_ndx_to_fw; 195239462Sdim uint32_t req_ndx_from_fw; 196239462Sdim uint32_t req_available; 197239462Sdim 198239462Sdim caddr_t resp_ptr; 199239462Sdim uint32_t resp_ndx_to_fw; 200239462Sdim uint32_t resp_ndx_from_fw; 201239462Sdim 202239462Sdim kmutex_t preq_lock; 203239462Sdim caddr_t preq_ptr; 204239462Sdim uint32_t preq_ndx_to_fw; 205239462Sdim uint32_t preq_ndx_from_fw; 206239462Sdim 207239462Sdim kcondvar_t rp_dereg_cv; /* for deregister cmd */ 208239462Sdim uint32_t rp_id_in_dereg; /* remote port in deregistering */ 209234285Sdim fct_status_t rp_dereg_status; 210234285Sdim 211234285Sdim caddr_t atio_ptr; 212234285Sdim uint16_t atio_ndx_to_fw; 213234285Sdim uint16_t atio_ndx_from_fw; 214234285Sdim 215234285Sdim kmutex_t dma_mem_lock; 216234285Sdim 217234285Sdim /* MailBox data */ 218234285Sdim kmutex_t mbox_lock; 219234285Sdim kcondvar_t mbox_cv; 220234285Sdim mbox_state_t mbox_io_state; 221251662Sdim mbox_cmd_t *mcp; 222251662Sdim qlt_nvram_t *nvram; 223251662Sdim 224251662Sdim uint8_t link_speed; /* Cached from intr routine */ 225251662Sdim uint16_t fw_major; 226251662Sdim uint16_t fw_minor; 227251662Sdim uint16_t fw_subminor; 228251662Sdim uint16_t fw_endaddrlo; 229251662Sdim uint16_t fw_endaddrhi; 230251662Sdim uint16_t fw_attr; 231251662Sdim 232251662Sdim uint32_t fw_addr01; 233251662Sdim uint32_t fw_length01; 234234285Sdim uint32_t *fw_code01; 235234285Sdim 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 263typedef 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 281typedef 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 */ 357typedef struct string_table_entry { 358 uint32_t value; 359 char *string; 360} string_table_t; 361 362char *prop_text(int prop_status); 363char *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 417void qlt_chg_endian(uint8_t *, size_t); 418 419void qlt_el_msg(qlt_state_t *qlt, const char *fn, int ce, ...); 420void 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