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