/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2009-2015 QLogic Corporation. All rights reserved. * Use is subject to license terms. */ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2009, 2015 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * Copyright 2015 Nexenta Systems, Inc. All rights reserved. */ #ifndef _QLT_H #define _QLT_H #include #include "qlt_regs.h" #ifdef __cplusplus extern "C" { #endif /* * Qlogic logging */ extern int enable_extended_logging; /* * Caution: 1) LOG will be available in debug/non-debug mode * 2) Anything which can potentially flood the log should be under * extended logging, and use QLT_EXT_LOG. * 3) Don't use QLT_EXT_LOG in performance-critical code path, such * as normal SCSI I/O code path. It could hurt system performance. * 4) Use kmdb to change enable_extened_logging in the fly to adjust * tracing */ #define QLT_EXT_LOG(log_ident, ...) \ if (enable_extended_logging) { \ stmf_trace(log_ident, __VA_ARGS__); \ } #define QLT_LOG(log_ident, ...) \ stmf_trace(log_ident, __VA_ARGS__) /* * Error codes. FSC stands for Failure sub code. */ #define QLT_FAILURE FCT_FCA_FAILURE #define QLT_SUCCESS FCT_SUCCESS #define QLT_FSC(x) ((uint64_t)(x) << 40) #define QLT_DMA_STUCK (QLT_FAILURE | QLT_FSC(1)) #define QLT_MAILBOX_STUCK (QLT_FAILURE | QLT_FSC(2)) #define QLT_ROM_STUCK (QLT_FAILURE | QLT_FSC(3)) #define QLT_UNEXPECTED_RESPONSE (QLT_FAILURE | QLT_FSC(4)) #define QLT_MBOX_FAILED (QLT_FAILURE | QLT_FSC(5)) #define QLT_MBOX_NOT_INITIALIZED (QLT_FAILURE | QLT_FSC(6)) #define QLT_MBOX_BUSY (QLT_FAILURE | QLT_FSC(7)) #define QLT_MBOX_ABORTED (QLT_FAILURE | QLT_FSC(8)) #define QLT_MBOX_TIMEOUT (QLT_FAILURE | QLT_FSC(9)) #define QLT_RESP_TIMEOUT (QLT_FAILURE | QLT_FSC(10)) #define QLT_FLASH_TIMEOUT (QLT_FAILURE | QLT_FSC(11)) #define QLT_FLASH_ACCESS_ERROR (QLT_FAILURE | QLT_FSC(12)) #define QLT_BAD_NVRAM_DATA (QLT_FAILURE | QLT_FSC(13)) #define QLT_FIRMWARE_ERROR_CODE (QLT_FAILURE | QLT_FSC(14)) #define QLT_FIRMWARE_ERROR(s, c1, c2) (QLT_FIRMWARE_ERROR_CODE | \ (((uint64_t)s) << 32) | (((uint64_t)c1) << 24) | ((uint64_t)c2)) extern uint32_t fw2400_code01[]; extern uint32_t fw2400_length01; extern uint32_t fw2400_addr01; extern uint32_t fw2400_code02[]; extern uint32_t fw2400_length02; extern uint32_t fw2400_addr02; extern uint32_t fw2500_code01[]; extern uint32_t fw2500_length01; extern uint32_t fw2500_addr01; extern uint32_t fw2500_code02[]; extern uint32_t fw2500_length02; extern uint32_t fw2500_addr02; extern uint32_t fw2700_code01[]; extern uint32_t fw2700_length01; extern uint32_t fw2700_addr01; extern uint32_t fw2700_code02[]; extern uint32_t fw2700_length02; extern uint32_t fw2700_addr02; extern uint32_t tmplt2700_code01[]; extern uint32_t tmplt2700_length01; extern uint32_t fw8100_code01[]; extern uint32_t fw8100_length01; extern uint32_t fw8100_addr01; extern uint32_t fw8100_code02[]; extern uint32_t fw8100_length02; extern uint32_t fw8100_addr02; extern uint32_t fw8300fc_code01[]; extern uint32_t fw8300fc_length01; extern uint32_t fw8300fc_addr01; extern uint32_t fw8300fc_code02[]; extern uint32_t fw8300fc_length02; extern uint32_t fw8300fc_addr02; typedef enum { MBOX_STATE_UNKNOWN = 0, MBOX_STATE_READY, MBOX_STATE_CMD_RUNNING, MBOX_STATE_CMD_DONE } mbox_state_t; /* * ISP mailbox Self-Test status codes */ #define MBS_ROM_IDLE 0 /* Firmware Alive. */ #define MBS_ROM_BUSY 4 /* Busy. */ #define MBS_ROM_CONFIG_ERR 0xF /* Board Config Error. */ #define MBS_ROM_STATUS_MASK 0xF #define MBS_FW_RUNNING 0x8400 /* firmware running. */ #define MBS_FW_CONFIG_ERR 0x8401 /* firmware config error */ /* * ISP mailbox commands */ #define MBC_LOAD_RAM 0x01 /* Load RAM. */ #define MBC_EXECUTE_FIRMWARE 0x02 /* Execute firmware. */ #define MBC_DUMP_RAM 0x03 /* Dump RAM. */ #define MBC_WRITE_RAM_WORD 0x04 /* Write RAM word. */ #define MBC_READ_RAM_WORD 0x05 /* Read RAM word. */ #define MBC_MPI_RAM 0x05 /* Load/dump MPI RAM. */ #define MBC_MAILBOX_REGISTER_TEST 0x06 /* Wrap incoming mailboxes */ #define MBC_VERIFY_CHECKSUM 0x07 /* Verify checksum. */ #define MBC_ABOUT_FIRMWARE 0x08 /* About Firmware. */ #define MBC_DUMP_RISC_RAM 0x0a /* Dump RISC RAM command. */ #define MBC_LOAD_RAM_EXTENDED 0x0b /* Load RAM extended. */ #define MBC_DUMP_RAM_EXTENDED 0x0c /* Dump RAM extended. */ #define MBC_WRITE_RAM_EXTENDED 0x0d /* Write RAM word. */ #define MBC_READ_RAM_EXTENDED 0x0f /* Read RAM extended. */ #define MBC_SERDES_TRANSMIT_PARAMETERS 0x10 /* Serdes Xmit Parameters */ #define MBC_2300_EXECUTE_IOCB 0x12 /* ISP2300 Execute IOCB cmd */ #define MBC_GET_IO_STATUS 0x12 /* ISP2422 Get I/O Status */ #define MBC_STOP_FIRMWARE 0x14 /* Stop firmware */ #define MBC_ABORT_COMMAND_IOCB 0x15 /* Abort IOCB command. */ #define MBC_ABORT_DEVICE 0x16 /* Abort device (ID/LUN). */ #define MBC_ABORT_TARGET 0x17 /* Abort target (ID). */ #define MBC_RESET 0x18 /* Target reset. */ #define MBC_XMIT_PARM 0x19 /* Change default xmit parms */ #define MBC_PORT_PARAM 0x1a /* Get/set port speed parms */ #define MBC_INIT_MQ 0x1f /* Initialize multiple queue */ #define MBC_GET_ID 0x20 /* Get loop id of ISP2200. */ #define MBC_GET_TIMEOUT_PARAMETERS 0x22 /* Get Timeout Parameters. */ #define MBC_TRACE_CONTROL 0x27 /* Trace control. */ #define MBC_GET_FIRMWARE_OPTIONS 0x28 /* Get firmware options */ #define MBC_READ_SFP 0x31 /* Read SFP. */ #define MBC_SET_ADDITIONAL_FIRMWARE_OPT 0x38 /* set firmware options */ #define OPT_PUREX_ENABLE (BIT_10) #define MBC_RESET_MENLO 0x3a /* Reset Menlo. */ #define MBC_RESTART_MPI 0x3d /* Restart MPI. */ #define MBC_FLASH_ACCESS 0x3e /* Flash Access Control */ #define MBC_LOOP_PORT_BYPASS 0x40 /* Loop Port Bypass. */ #define MBC_LOOP_PORT_ENABLE 0x41 /* Loop Port Enable. */ #define MBC_GET_RESOURCE_COUNTS 0x42 /* Get Resource Counts. */ #define MBC_NON_PARTICIPATE 0x43 /* Non-Participating Mode. */ #define MBC_ECHO 0x44 /* ELS ECHO */ #define MBC_DIAGNOSTIC_LOOP_BACK 0x45 /* Diagnostic loop back. */ #define MBC_ONLINE_SELF_TEST 0x46 /* Online self-test. */ #define MBC_ENHANCED_GET_PORT_DATABASE 0x47 /* Get Port Database + login */ #define MBC_INITIALIZE_MULTI_ID_FW 0x48 /* Initialize multi-id fw */ #define MBC_GET_DCBX_PARAMS 0x51 /* Get DCBX parameters */ #define MBC_RESET_LINK_STATUS 0x52 /* Reset Link Error Status */ #define MBC_EXECUTE_IOCB 0x54 /* 64 Bit Execute IOCB cmd. */ #define MBC_SEND_RNID_ELS 0x57 /* Send RNID ELS request */ #define MBC_SET_PARAMETERS 0x59 /* Set parameters */ #define RNID_PARAMS_DF_FMT 0x00 #define RNID_PARAMS_E0_FMT 0x01 #define PUREX_ELS_CMDS 0x05 #define FLOGI_PARAMS 0x06 #define PARAM_TYPE_FIELD_MASK 0xff #define PARAM_TYPE_FIELD_SHIFT 8 #define PARAM_TYPE(type) ((type & PARAM_TYPE_FIELD_MASK) << \ PARAM_TYPE_FIELD_SHIFT) #define MBC_GET_PARAMETERS 0x5a /* Get RNID parameters */ #define MBC_DATA_RATE 0x5d /* Data Rate */ #define MBC_INITIALIZE_FIRMWARE 0x60 /* Initialize firmware */ #define MBC_INITIATE_LIP 0x62 /* Initiate LIP */ #define MBC_GET_FC_AL_POSITION_MAP 0x63 /* Get FC_AL Position Map. */ #define MBC_GET_PORT_DATABASE 0x64 /* Get Port Database. */ #define MBC_CLEAR_ACA 0x65 /* Clear ACA. */ #define MBC_TARGET_RESET 0x66 /* Target Reset. */ #define MBC_CLEAR_TASK_SET 0x67 /* Clear Task Set. */ #define MBC_ABORT_TASK_SET 0x68 /* Abort Task Set. */ #define MBC_GET_FIRMWARE_STATE 0x69 /* Get firmware state. */ #define MBC_GET_PORT_NAME 0x6a /* Get port name. */ #define MBC_GET_LINK_STATUS 0x6b /* Get Link Status. */ #define MBC_LIP_RESET 0x6c /* LIP reset. */ #define MBC_GET_STATUS_COUNTS 0x6d /* Get Link Statistics and */ /* Private Data Counts */ #define MBC_SEND_SNS_COMMAND 0x6e /* Send Simple Name Server */ #define MBC_LOGIN_FABRIC_PORT 0x6f /* Login fabric port. */ #define MBC_SEND_CHANGE_REQUEST 0x70 /* Send Change Request. */ #define MBC_LOGOUT_FABRIC_PORT 0x71 /* Logout fabric port. */ #define MBC_LIP_FULL_LOGIN 0x72 /* Full login LIP. */ #define MBC_LOGIN_LOOP_PORT 0x74 /* Login Loop Port. */ #define MBC_PORT_NODE_NAME_LIST 0x75 /* Get port/node name list */ #define MBC_INITIALIZE_IP 0x77 /* Initialize IP */ #define MBC_SEND_FARP_REQ_COMMAND 0x78 /* FARP request. */ #define MBC_UNLOAD_IP 0x79 /* Unload IP */ #define MBC_GET_XGMAC_STATS 0x7a /* Get XGMAC Statistics. */ #define MBC_GET_ID_LIST 0x7c /* Get port ID list. */ #define MBC_SEND_LFA_COMMAND 0x7d /* Send Loop Fabric Address */ #define MBC_LUN_RESET 0x7e /* Send Task mgmt LUN reset */ #define MBC_IDC_REQUEST 0x100 /* IDC request */ #define MBC_IDC_ACK 0x101 /* IDC acknowledge */ #define MBC_IDC_TIME_EXTEND 0x102 /* IDC extend time */ #define MBC_PORT_RESET 0x120 /* Port Reset */ #define MBC_SET_PORT_CONFIG 0x122 /* Set port configuration */ #define MBC_GET_PORT_CONFIG 0x123 /* Get port configuration */ #define IOCB_SIZE 64 #define MAX_SPEED_MASK 0x0000000F #define MAX_PORTS_MASK 0x000000F0 #define MAX_SPEED_16G 0x0 #define MAX_SPEED_32G 0x1 /* * These should not be constents but should be obtained from fw. */ #define QLT_MAX_LOGINS 2048 #define QLT_MAX_XCHGES 2048 #define MAX_MBOXES 32 #define MBOX_TIMEOUT (14*1000*1000) /* for Palladium */ #define DEREG_RP_TIMEOUT (22*1000*1000) typedef struct { uint16_t to_fw[MAX_MBOXES]; uint32_t to_fw_mask; uint16_t from_fw[MAX_MBOXES]; uint32_t from_fw_mask; stmf_data_buf_t *dbuf; } mbox_cmd_t; typedef struct qlt_abts_cmd { uint8_t buf[IOCB_SIZE]; uint16_t qid; } qlt_abts_cmd_t; struct qlt_dmem_bucket; #define QLT_INTR_FIXED 0x1 #define QLT_INTR_MSI 0x2 #define QLT_INTR_MSIX 0x4 #define QL_LOG_ENTRIES 16384 #define QL_LOG_LENGTH 128 typedef struct qlt_trace_entry { timespec_t hs_time; char buf[QL_LOG_LENGTH]; } qlt_trace_entry_t; typedef struct qlt_trace_desc { kmutex_t mutex; uint32_t nentries; uint32_t nindex; uint32_t start; uint32_t end; uint32_t csize; uint32_t count; size_t trace_buffer_size; qlt_trace_entry_t *trace_buffer; } qlt_trace_desc_t; typedef struct qlt_mq_req_ptr_blk { kmutex_t mq_lock; caddr_t mq_ptr; uint32_t mq_ndx_to_fw; uint32_t mq_ndx_from_fw; uint32_t mq_available; ddi_dma_handle_t queue_mem_mq_dma_handle; ddi_acc_handle_t queue_mem_mq_acc_handle; caddr_t queue_mem_mq_base_addr; ddi_dma_cookie_t queue_mem_mq_cookie; } qlt_mq_req_ptr_blk_t; typedef struct qlt_mq_rsp_ptr_blk { kmutex_t mq_lock; caddr_t mq_ptr; uint32_t mq_ndx_to_fw; uint32_t mq_ndx_from_fw; ddi_dma_handle_t queue_mem_mq_dma_handle; ddi_acc_handle_t queue_mem_mq_acc_handle; caddr_t queue_mem_mq_base_addr; ddi_dma_cookie_t queue_mem_mq_cookie; } qlt_mq_rsp_ptr_blk_t; typedef struct qlt_state { dev_info_t *dip; char qlt_minor_name[16]; char qlt_port_alias[16]; fct_local_port_t *qlt_port; struct qlt_dmem_bucket **dmem_buckets; struct qlt_dma_handle_pool *qlt_dma_handle_pool; int instance; uint8_t qlt_state:7, qlt_state_not_acked:1; uint8_t qlt_intr_enabled:1, qlt_25xx_chip:1, qlt_stay_offline:1, qlt_link_up, qlt_81xx_chip:1, qlt_mq_enabled:1, qlt_83xx_chip:1, qlt_fcoe_enabled:1; uint8_t qlt_27xx_chip:1, rsvd0:7; uint8_t cur_topology; /* Registers */ caddr_t regs; ddi_acc_handle_t regs_acc_handle; ddi_acc_handle_t pcicfg_acc_handle; caddr_t msix_base; ddi_acc_handle_t msix_acc_handle; caddr_t mq_reg_base; ddi_acc_handle_t mq_reg_acc_handle; /* Interrupt stuff */ kmutex_t intr_lock; /* Only used by intr routine */ int intr_sneak_counter; ddi_intr_handle_t *htable; int intr_size; int intr_cnt; uint_t intr_pri; int intr_cap; int intr_flags; /* Queues */ ddi_dma_handle_t queue_mem_dma_handle; ddi_acc_handle_t queue_mem_acc_handle; caddr_t queue_mem_ptr; ddi_dma_cookie_t queue_mem_cookie; /* * kmutex_t req_lock; * caddr_t req_ptr; * uint32_t req_ndx_to_fw; * uint32_t req_ndx_from_fw; * uint32_t req_available; */ qlt_mq_req_ptr_blk_t *mq_req; qlt_mq_rsp_ptr_blk_t *mq_resp; /* MQMQ */ uint32_t qlt_queue_cnt; kmutex_t qlock; uint32_t last_qi; kmutex_t preq_lock; caddr_t preq_ptr; uint32_t preq_ndx_to_fw; uint32_t preq_ndx_from_fw; kcondvar_t rp_dereg_cv; /* for deregister cmd */ uint32_t rp_id_in_dereg; /* remote port in deregistering */ fct_status_t rp_dereg_status; caddr_t atio_ptr; uint16_t atio_ndx_to_fw; uint16_t atio_ndx_from_fw; kmutex_t dma_mem_lock; /* MailBox data */ kmutex_t mbox_lock; kcondvar_t mbox_cv; mbox_state_t mbox_io_state; mbox_cmd_t *mcp; qlt_nvram_t *nvram; uint32_t *vpd; qlt_rom_image_t rimage[6]; uint8_t link_speed; /* Cached from intr routine */ uint16_t fw_major; uint16_t fw_minor; uint16_t fw_subminor; uint16_t fw_endaddrlo; uint16_t fw_endaddrhi; uint16_t fw_attr; uint32_t fw_addr01; uint32_t fw_length01; uint32_t *fw_code01; uint32_t fw_addr02; uint32_t fw_length02; uint32_t *fw_code02; uint32_t fw_ext_memory_end; uint32_t fw_shared_ram_start; uint32_t fw_shared_ram_end; uint32_t fw_ddr_ram_start; uint32_t fw_ddr_ram_end; uint32_t qlt_ioctl_flags; kmutex_t qlt_ioctl_lock; uint32_t fw_dump_size; caddr_t qlt_fwdump_buf; /* FWDUMP will use ioctl flags/lock */ uint32_t qlt_change_state_flags; /* Cached for ACK handling */ /* Dump template */ ddi_dma_handle_t dmp_template_dma_handle; ddi_acc_handle_t dmp_template_acc_handle; caddr_t dmp_template_addr; ddi_dma_cookie_t dmp_template_cookie; uint32_t fw_bin_dump_size; caddr_t fw_bin_dump_buf; uint32_t fw_ascii_dump_size; qlt_trace_desc_t *qlt_trace_desc; uint32_t qlt_log_entries; uint8_t qlt_eel_level; /* extended error logging */ /* temp ref & stat counters */ uint32_t qlt_bucketcnt[5]; /* element 0 = 2k */ uint64_t qlt_bufref[5]; /* element 0 = 2k */ uint64_t qlt_bumpbucket; /* bigger buffer supplied */ uint64_t qlt_pmintry; uint64_t qlt_pmin_ok; uint32_t qlt_27xx_speed; uint32_t qlt_atio_reproc_cnt; uint32_t qlt_resp_reproc_cnt; } qlt_state_t; /* * FWDUMP flags (part of IOCTL flags) */ #define QLT_FWDUMP_INPROGRESS 0x0100 /* if it's dumping now */ #define QLT_FWDUMP_TRIGGERED_BY_USER 0x0200 /* if users triggered it */ #define QLT_FWDUMP_FETCHED_BY_USER 0x0400 /* if users have viewed it */ #define QLT_FWDUMP_ISVALID 0x0800 /* * IOCTL supporting stuff */ #define QLT_IOCTL_FLAG_MASK 0xFF #define QLT_IOCTL_FLAG_IDLE 0x00 #define QLT_IOCTL_FLAG_OPEN 0x01 #define QLT_IOCTL_FLAG_EXCL 0x02 typedef struct qlt_cmd { fct_cmd_t *cmd; uint32_t handle; stmf_data_buf_t *dbuf; /* dbuf with handle 0 for SCSI cmds */ stmf_data_buf_t *dbuf_rsp_iu; /* dbuf for possible FCP_RSP IU */ uint32_t fw_xchg_addr; uint16_t oxid; uint16_t flags; union { uint16_t resp_offset; uint8_t atio_byte3; } param; uint16_t qid; } qlt_cmd_t; /* * cmd flags */ #define QLT_CMD_ABORTING 1 #define QLT_CMD_ABORTED 2 #define QLT_CMD_TYPE_SOLICITED 4 typedef struct { int dummy; } qlt_remote_port_t; #define REQUEST_QUEUE_ENTRIES 2048 #define RESPONSE_QUEUE_ENTRIES 2048 #define ATIO_QUEUE_ENTRIES 2048 #define PRIORITY_QUEUE_ENTRIES 128 #define REQUEST_QUEUE_OFFSET 0 #define RESPONSE_QUEUE_OFFSET (REQUEST_QUEUE_OFFSET + \ (REQUEST_QUEUE_ENTRIES * IOCB_SIZE)) #define ATIO_QUEUE_OFFSET (RESPONSE_QUEUE_OFFSET + \ (RESPONSE_QUEUE_ENTRIES * IOCB_SIZE)) #define PRIORITY_QUEUE_OFFSET (ATIO_QUEUE_OFFSET + \ (ATIO_QUEUE_ENTRIES * IOCB_SIZE)) #define MBOX_DMA_MEM_SIZE 4096 #define MBOX_DMA_MEM_OFFSET (PRIORITY_QUEUE_OFFSET + \ (PRIORITY_QUEUE_ENTRIES * IOCB_SIZE)) #define TOTAL_DMA_MEM_SIZE (MBOX_DMA_MEM_OFFSET + MBOX_DMA_MEM_SIZE) #define QLT_MAX_ITERATIONS_PER_INTR 32 #define REQUEST_QUEUE_MQ_ENTRIES 512 #define REQUEST_QUEUE_MQ_SIZE (REQUEST_QUEUE_MQ_ENTRIES * IOCB_SIZE) #define RESPONSE_QUEUE_MQ_ENTRIES 512 #define RESPONSE_QUEUE_MQ_SIZE (RESPONSE_QUEUE_MQ_ENTRIES * IOCB_SIZE) #define REG_RD8(qlt, addr) \ ddi_get8(qlt->regs_acc_handle, (uint8_t *)(qlt->regs + addr)) #define REG_RD16(qlt, addr) \ ddi_get16(qlt->regs_acc_handle, (uint16_t *)(qlt->regs + addr)) #define REG_RD32(qlt, addr) \ ddi_get32(qlt->regs_acc_handle, (uint32_t *)(qlt->regs + addr)) #define REG_WR16(qlt, addr, data) \ ddi_put16(qlt->regs_acc_handle, (uint16_t *)(qlt->regs + addr), \ (uint16_t)(data)) #define REG_WR32(qlt, addr, data) \ ddi_put32(qlt->regs_acc_handle, (uint32_t *)(qlt->regs + addr), \ (uint32_t)(data)) #define PCICFG_RD8(qlt, addr) \ pci_config_get8(qlt->pcicfg_acc_handle, (off_t)(addr)) #define PCICFG_RD16(qlt, addr) \ pci_config_get16(qlt->pcicfg_acc_handle, (off_t)(addr)) #define PCICFG_RD32(qlt, addr) \ pci_config_get32(qlt->pcicfg_acc_handle, (off_t)(addr)) #define PCICFG_WR16(qlt, addr, data) \ pci_config_put16(qlt->pcicfg_acc_handle, (off_t)(addr), \ (uint16_t)(data)) #define PCICFG_WR32(qlt, addr, data) \ pci_config_put32(qlt->pcicfg_acc_handle, (off_t)(addr), \ (uint32_t)(data)) /* * Used for Req/Resp queue 0 and atio queue only */ #define QMEM_RD16(qlt, addr) \ ddi_get16(qlt->queue_mem_acc_handle, (uint16_t *)(addr)) #define DMEM_RD16(qlt, addr) LE_16((uint16_t)(*((uint16_t *)(addr)))) #define QMEM_RD32(qlt, addr) \ ddi_get32(qlt->queue_mem_acc_handle, (uint32_t *)(addr)) #define DMEM_RD32(qlt, addr) LE_32((uint32_t)(*((uint32_t *)(addr)))) /* * #define QMEM_RD64(qlt, addr) \ * ddi_get64(qlt->queue_mem_acc_handle, (uint64_t *)(addr)) */ #define QMEM_WR16(qlt, addr, data) \ ddi_put16(qlt->queue_mem_acc_handle, (uint16_t *)(addr), \ (uint16_t)(data)) #define DMEM_WR16(qlt, addr, data) (*((uint16_t *)(addr)) = \ (uint16_t)LE_16((uint16_t)(data))) #define QMEM_WR32(qlt, addr, data) \ ddi_put32(qlt->queue_mem_acc_handle, (uint32_t *)(addr), \ (uint32_t)(data)) #define DMEM_WR32(qlt, addr, data) (*((uint32_t *)(addr)) = \ LE_32((uint32_t)(data))) /* * [QD]MEM is always little endian so the [QD]MEM_WR64 macro works for * both sparc and x86. */ #define QMEM_WR64(qlt, addr, data) \ QMEM_WR32(qlt, addr, (data & 0xffffffff)), \ QMEM_WR32(qlt, (addr)+4, ((uint64_t)data) >> 32) #define DMEM_WR64(qlt, addr, data) \ DMEM_WR32(qlt, addr, (data & 0xffffffff)), \ DMEM_WR32(qlt, (addr)+4, ((uint64_t)data) >> 32) /* * Multi Queue suppport since the queue access handles are * allocated separetly. */ #define QMEM_RD16_REQ(qlt, qi, addr) \ (qi == 0) ? QMEM_RD16(qlt, addr) : \ ddi_get16(qlt->mq_req[qi].queue_mem_mq_acc_handle, \ (uint16_t *)(addr)) #define QMEM_RD16_RSPQ(qlt, qi, addr) \ (qi == 0) ? QMEM_RD16(qlt, addr) : \ ddi_get16(qlt->mq_resp[qi].queue_mem_mq_acc_handle, \ (uint16_t *)(addr)) #define QMEM_RD32_REQ(qlt, qi, addr) \ (qi == 0) ? QMEM_RD32(qlt, addr) : \ ddi_get32(qlt->mq_req[qi].queue_mem_mq_acc_handle, \ (uint32_t *)(addr)) #define QMEM_RD32_RSPQ(qlt, qi, addr) \ (qi == 0) ? QMEM_RD32(qlt, addr) : \ ddi_get32(qlt->mq_resp[qi].queue_mem_mq_acc_handle, \ (uint32_t *)(addr)) #define QMEM_WR16_REQ(qlt, qi, addr, data) \ (qi == 0) ? QMEM_WR16(qlt, addr, data) : \ ddi_put16(qlt->mq_req[qi].queue_mem_mq_acc_handle, \ (uint16_t *)(addr), (uint16_t)(data)) #define QMEM_WR16_RSPQ(qlt, qi, addr, data) \ (qi == 0) ? QMEM_WR16(qlt, addr, data) : \ ddi_put16(qlt->mq_resp[qi].queue_mem_mq_acc_handle, \ (uint16_t *)(addr), (uint16_t)(data)) #define QMEM_WR32_REQ(qlt, qi, addr, data) \ (qi == 0) ? QMEM_WR32(qlt, addr, data) : \ ddi_put32(qlt->mq_req[qi].queue_mem_mq_acc_handle, \ (uint32_t *)(addr), (uint32_t)(data)) #define QMEM_WR32_RSPQ(qlt, qi, addr, data) \ (qi == 0) ? QMEM_WR32(qlt, addr, data) : \ ddi_put32(qlt->mq_resp[qi].queue_mem_mq_acc_handle, \ (uint32_t *)(addr), (uint32_t)(data)) /* * [QD]MEM is always little endian so the [QD]MEM_WR64 macro works for * both sparc and x86. */ #define QMEM_WR64_REQ(qlt, qi, addr, data) \ (qi == 0) ? QMEM_WR64(qlt, addr, data) : \ QMEM_WR32_REQ(qlt, qi, addr, (data & 0xffffffff)), \ QMEM_WR32_REQ(qlt, qi, (addr)+4, ((uint64_t)data) >> 32) #define QMEM_WR64_RSPQ(qlt, qi, addr, data) \ (qi == 0) ? QMEM_WR64(qlt, addr, data) : \ QMEM_WR32_RSPQ(qlt, qi, addr, (data & 0xffffffff)), \ QMEM_WR32_RSPQ(qlt, qi, (addr)+4, ((uint64_t)data) >> 32) /* * MBAR access for Multi-Queue */ #define MQBAR_RD16(qlt, addr) \ ddi_get16(qlt->mq_reg_acc_handle, (uint16_t *)(qlt->mq_reg_base + addr)) #define MQBAR_RD32(qlt, addr) \ ddi_get32(qlt->mq_reg_acc_handle, (uint32_t *)(qlt->mq_reg_base + addr)) #define MQBAR_WR16(qlt, addr, data) \ ddi_put16(qlt->mq_reg_acc_handle, \ (uint16_t *)(qlt->mq_reg_base + addr), \ (uint16_t)(data)) #define MQBAR_WR32(qlt, addr, data) \ ddi_put32(qlt->mq_reg_acc_handle, \ (uint32_t *)(qlt->mq_reg_base + addr), \ (uint32_t)(data)) /* * Structure used to associate values with strings which describe them. */ typedef struct string_table_entry { uint32_t value; char *string; } string_table_t; char *prop_text(int prop_status); char *value2string(string_table_t *entry, int value, int delimiter); #define PROP_STATUS_DELIMITER ((uint32_t)0xFFFF) #define DDI_PROP_STATUS() \ { \ {DDI_PROP_SUCCESS, "DDI_PROP_SUCCESS"}, \ {DDI_PROP_NOT_FOUND, "DDI_PROP_NOT_FOUND"}, \ {DDI_PROP_UNDEFINED, "DDI_PROP_UNDEFINED"}, \ {DDI_PROP_NO_MEMORY, "DDI_PROP_NO_MEMORY"}, \ {DDI_PROP_INVAL_ARG, "DDI_PROP_INVAL_ARG"}, \ {DDI_PROP_BUF_TOO_SMALL, "DDI_PROP_BUF_TOO_SMALL"}, \ {DDI_PROP_CANNOT_DECODE, "DDI_PROP_CANNOT_DECODE"}, \ {DDI_PROP_CANNOT_ENCODE, "DDI_PROP_CANNOT_ENCODE"}, \ {DDI_PROP_END_OF_DATA, "DDI_PROP_END_OF_DATA"}, \ {PROP_STATUS_DELIMITER, "DDI_PROP_UNKNOWN"} \ } #ifndef TRUE #define TRUE B_TRUE #endif #ifndef FALSE #define FALSE B_FALSE #endif /* Little endian machine correction defines. */ #ifdef _LITTLE_ENDIAN #define LITTLE_ENDIAN_16(x) #define LITTLE_ENDIAN_24(x) #define LITTLE_ENDIAN_32(x) #define LITTLE_ENDIAN_64(x) #define LITTLE_ENDIAN(bp, bytes) #define BIG_ENDIAN_16(x) qlt_chg_endian((uint8_t *)x, 2) #define BIG_ENDIAN_24(x) qlt_chg_endian((uint8_t *)x, 3) #define BIG_ENDIAN_32(x) qlt_chg_endian((uint8_t *)x, 4) #define BIG_ENDIAN_64(x) qlt_chg_endian((uint8_t *)x, 8) #define BIG_ENDIAN(bp, bytes) qlt_chg_endian((uint8_t *)bp, bytes) #endif /* _LITTLE_ENDIAN */ /* Big endian machine correction defines. */ #ifdef _BIG_ENDIAN #define LITTLE_ENDIAN_16(x) qlt_chg_endian((uint8_t *)x, 2) #define LITTLE_ENDIAN_24(x) qlt_chg_endian((uint8_t *)x, 3) #define LITTLE_ENDIAN_32(x) qlt_chg_endian((uint8_t *)x, 4) #define LITTLE_ENDIAN_64(x) qlt_chg_endian((uint8_t *)x, 8) #define LITTLE_ENDIAN(bp, bytes) qlt_chg_endian((uint8_t *)bp, bytes) #define BIG_ENDIAN_16(x) #define BIG_ENDIAN_24(x) #define BIG_ENDIAN_32(x) #define BIG_ENDIAN_64(x) #define BIG_ENDIAN(bp, bytes) #endif /* _BIG_ENDIAN */ #define LSB(x) (uint8_t)(x) #define MSB(x) (uint8_t)((uint16_t)(x) >> 8) #define MSW(x) (uint16_t)((uint32_t)(x) >> 16) #define LSW(x) (uint16_t)(x) #define LSD(x) (uint32_t)(x) #define MSD(x) (uint32_t)((uint64_t)(x) >> 32) #define SHORT_TO_LONG(lsw, msw) (uint32_t)((uint16_t)msw << 16 | (uint16_t)lsw) #define CHAR_TO_SHORT(lsb, msb) (uint16_t)((uint8_t)msb << 8 | (uint8_t)lsb) #define CHAR_TO_LONG(lsb, b1, b2, msb) \ (uint32_t)(SHORT_TO_LONG(CHAR_TO_SHORT(lsb, b1), \ CHAR_TO_SHORT(b2, msb))) void qlt_chg_endian(uint8_t *, size_t); #define TRACE_BUFFER_LOCK(qlt) mutex_enter(&qlt->qlt_trace_desc->mutex) #define TRACE_BUFFER_UNLOCK(qlt) mutex_exit(&qlt->qlt_trace_desc->mutex) #define QL_BANG "!" void qlt_el_msg(qlt_state_t *qlt, const char *fn, int ce, ...); void qlt_dump_el_trace_buffer(qlt_state_t *qlt); #define EL(qlt, ...) qlt_el_msg(qlt, __func__, CE_CONT, __VA_ARGS__); #define EL_TRACE_BUF_SIZE 8192 #define EL_BUFFER_RESERVE 256 #define DEBUG_STK_DEPTH 24 #define EL_TRACE_BUF_SIZE 8192 #ifdef __cplusplus } #endif #endif /* _QLT_H */