/** * qla4xxx_get_firmware_state - gets firmware state of HBA * @ha: Pointer to host adapter structure. **/ int qla4xxx_get_firmware_state(struct scsi_qla_host * ha) { uint32_t mbox_cmd[MBOX_REG_COUNT]; uint32_t mbox_sts[MBOX_REG_COUNT]; /* Get firmware version */ memset(&mbox_cmd, 0, sizeof(mbox_cmd)); memset(&mbox_sts, 0, sizeof(mbox_sts)); mbox_cmd[0] = MBOX_CMD_GET_FW_STATE; if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 4, &mbox_cmd[0], &mbox_sts[0]) != QLA_SUCCESS) { DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_FW_STATE failed w/ " "status %04X\n", ha->host_no, __func__, mbox_sts[0])); return QLA_ERROR; } ha->firmware_state = mbox_sts[1]; ha->board_id = mbox_sts[2]; ha->addl_fw_state = mbox_sts[3]; DEBUG2(printk("scsi%ld: %s firmware_state=0x%x\n", ha->host_no, __func__, ha->firmware_state);) return QLA_SUCCESS;
uint8_t qla4xxx_set_ifcb(scsi_qla_host_t *ha, uint32_t *mbox_cmd, uint32_t *mbox_sts, dma_addr_t init_fw_cb_dma) { memset(mbox_cmd, 0, sizeof(mbox_cmd[0]) * MBOX_REG_COUNT); memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT); mbox_cmd[0] = MBOX_CMD_INITIALIZE_FIRMWARE; mbox_cmd[1] = 0; mbox_cmd[2] = LSDW(init_fw_cb_dma); mbox_cmd[3] = MSDW(init_fw_cb_dma); if (ha->ifcb_size > LEGACY_IFCB_SIZE){ mbox_cmd[4] = ha->ifcb_size; mbox_cmd[5] = (IFCB_VER_MAX << 8) | IFCB_VER_MIN; } if (qla4xxx_mailbox_command(ha, 6, 6, mbox_cmd, mbox_sts) != QLA_SUCCESS) { QL4PRINT(QLP2, printk("scsi%d: %s: " "MBOX_CMD_INITIALIZE_FIRMWARE failed w/ status %04X\n", ha->host_no, __func__, mbox_sts[0])); { int i; for (i=0; i<MBOX_REG_COUNT; i++) { QL4PRINT(QLP2, printk("mbox_cmd[%d] = %08x, " "mbox_sts[%d] = %08x\n", i, mbox_cmd[i], i, mbox_sts[i])); } } return (QLA_ERROR); } return (QLA_SUCCESS); }
uint8_t qla4xxx_conn_close_sess_logout(scsi_qla_host_t *ha, uint16_t fw_ddb_index, uint16_t connection_id, uint16_t option) { uint32_t mbox_cmd[MBOX_REG_COUNT]; uint32_t mbox_sts[MBOX_REG_COUNT]; memset(&mbox_cmd, 0, sizeof(mbox_cmd)); memset(&mbox_sts, 0, sizeof(mbox_sts)); mbox_cmd[0] = MBOX_CMD_CONN_CLOSE_SESS_LOGOUT; mbox_cmd[1] = fw_ddb_index; mbox_cmd[2] = connection_id; mbox_cmd[3] = option; if (qla4xxx_mailbox_command(ha, 4, 2, &mbox_cmd[0], &mbox_sts[0]) != QLA_SUCCESS) { QL4PRINT(QLP2, printk("scsi%d: %s: MBOX_CMD_CONN_CLOSE_SESS_LOGOUT " "option %04x failed sts %04X %04X", ha->host_no, __func__, option, mbox_sts[0], mbox_sts[1])); if (mbox_sts[0] == MBOX_STS_COMMAND_ERROR) { QL4PRINT(QLP2, printk(", reason %04X\n", mbox_sts[1])); } else { QL4PRINT(QLP2, printk("\n")); } } return(QLA_SUCCESS); }
/** * qla4xxx_get_dhcp_ip_address - gets HBA ip address via DHCP * @ha: Pointer to host adapter structure. **/ int qla4xxx_get_dhcp_ip_address(struct scsi_qla_host * ha) { struct init_fw_ctrl_blk *init_fw_cb; dma_addr_t init_fw_cb_dma; uint32_t mbox_cmd[MBOX_REG_COUNT]; uint32_t mbox_sts[MBOX_REG_COUNT]; init_fw_cb = dma_alloc_coherent(&ha->pdev->dev, sizeof(struct init_fw_ctrl_blk), &init_fw_cb_dma, GFP_KERNEL); if (init_fw_cb == NULL) { printk("scsi%ld: %s: Unable to alloc init_cb\n", ha->host_no, __func__); return 10; } /* Get Initialize Firmware Control Block. */ memset(&mbox_cmd, 0, sizeof(mbox_cmd)); memset(&mbox_sts, 0, sizeof(mbox_sts)); memset(init_fw_cb, 0, sizeof(struct init_fw_ctrl_blk)); mbox_cmd[0] = MBOX_CMD_GET_INIT_FW_CTRL_BLOCK; mbox_cmd[2] = LSDW(init_fw_cb_dma); mbox_cmd[3] = MSDW(init_fw_cb_dma); mbox_cmd[4] = sizeof(struct init_fw_ctrl_blk); if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]) != QLA_SUCCESS) { DEBUG2(printk("scsi%ld: %s: Failed to get init_fw_ctrl_blk\n", ha->host_no, __func__)); dma_free_coherent(&ha->pdev->dev, sizeof(struct init_fw_ctrl_blk), init_fw_cb, init_fw_cb_dma); return QLA_ERROR; } /* Save IP Address. */ memcpy(ha->ip_address, init_fw_cb->pri.ipv4_addr, min(sizeof(ha->ip_address), sizeof(init_fw_cb->pri.ipv4_addr))); memcpy(ha->subnet_mask, init_fw_cb->pri.ipv4_subnet, min(sizeof(ha->subnet_mask), sizeof(init_fw_cb->pri.ipv4_subnet))); memcpy(ha->gateway, init_fw_cb->pri.ipv4_gw_addr, min(sizeof(ha->gateway), sizeof(init_fw_cb->pri.ipv4_gw_addr))); dma_free_coherent(&ha->pdev->dev, sizeof(struct init_fw_ctrl_blk), init_fw_cb, init_fw_cb_dma); return QLA_SUCCESS; }
uint8_t qla4xxx_mbx_test(scsi_qla_host_t *ha) { uint32_t mbox_cmd[MBOX_REG_COUNT]; uint32_t mbox_sts[MBOX_REG_COUNT]; int i; uint8_t status; memset(&mbox_cmd, 0, sizeof(mbox_cmd)); memset(&mbox_sts, 0, sizeof(mbox_sts)); mbox_cmd[0] = MBOX_CMD_REGISTER_TEST; mbox_cmd[1] = 0x11111111; mbox_cmd[2] = 0x22222222; mbox_cmd[3] = 0x33333333; mbox_cmd[4] = 0x44444444; mbox_cmd[5] = 0x55555555; mbox_cmd[6] = 0x66666666; mbox_cmd[7] = 0x77777777; if (qla4xxx_mailbox_command(ha, 8, 8, &mbox_cmd[0], &mbox_sts[0]) != QLA_SUCCESS) { QL4PRINT(QLP2, printk("scsi%d: REGISTER_TEST failed, mbox_sts = 0x%x\n", ha->host_no, mbox_sts[0])); return(QLA_ERROR); } if (mbox_sts[1] != 0x11111111 || mbox_sts[2] != 0x22222222 || mbox_sts[3] != 0x33333333 || mbox_sts[4] != 0x44444444 || mbox_sts[5] != 0x55555555 || mbox_sts[6] != 0x66666666 || mbox_sts[7] != 0x77777777) { QL4PRINT(QLP2, printk("scsi%d: REGISTER_TEST failed\n", ha->host_no)); status = QLA_ERROR; } else { QL4PRINT(QLP2, printk("scsi%d: REGISTER_TEST succeded\n", ha->host_no)); status = QLA_SUCCESS; } for (i = 0; i < 8; i++) { QL4PRINT(QLP2, printk("scsi%d: %s: MBX%d = 0x%x\n", ha->host_no, __func__, i, mbox_cmd[i])); } return(status); }
/* * Mailbox commands available for testing purposes, * just in case we need them. */ uint8_t qla4xxx_send_noop(scsi_qla_host_t *ha) { uint32_t mbox_cmd[MBOX_REG_COUNT]; uint32_t mbox_sts[MBOX_REG_COUNT]; memset(&mbox_cmd, 0, sizeof(mbox_cmd)); memset(&mbox_sts, 0, sizeof(mbox_sts)); mbox_cmd[0] = MBOX_CMD_NOP; if (qla4xxx_mailbox_command(ha, 1, 1, &mbox_cmd[0], &mbox_sts[0]) != QLA_SUCCESS) { QL4PRINT(QLP2, printk("scsi%d: NOP failed\n", ha->host_no)); return(QLA_ERROR); } else { QL4PRINT(QLP2, printk("scsi%d: NOP succeded\n", ha->host_no)); return(QLA_SUCCESS); } }
uint8_t qla4xxx_get_ifcb(scsi_qla_host_t *ha, uint32_t *mbox_cmd, uint32_t *mbox_sts, dma_addr_t init_fw_cb_dma) { memset(mbox_cmd, 0, sizeof(mbox_cmd[0]) * MBOX_REG_COUNT); memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT); mbox_cmd[0] = MBOX_CMD_GET_INIT_FW_CTRL_BLOCK; mbox_cmd[2] = LSDW(init_fw_cb_dma); mbox_cmd[3] = MSDW(init_fw_cb_dma); if (init_fw_cb_dma != 0 && ha->ifcb_size > LEGACY_IFCB_SIZE){ mbox_cmd[4] = ha->ifcb_size; } if (qla4xxx_mailbox_command(ha, 5, 5, mbox_cmd, mbox_sts) != QLA_SUCCESS) { if (init_fw_cb_dma == 0 && mbox_sts[0] == MBOX_STS_COMMAND_PARAMETER_ERROR) { /* Other valid info returned in mailbox status registers */ return (QLA_SUCCESS); } QL4PRINT(QLP2, printk("scsi%d: %s: " "MBOX_CMD_GET_INIT_FW_CTRL_BLOCK failed w/ status %04X\n", ha->host_no, __func__, mbox_sts[0])); { int i; for (i=0; i<MBOX_REG_COUNT; i++) { QL4PRINT(QLP2, printk("mbox_cmd[%d] = %08x, " "mbox_sts[%d] = %08x\n", i, mbox_cmd[i], i, mbox_sts[i])); } } return (QLA_ERROR); } return (QLA_SUCCESS); }
uint8_t qla4xxx_clear_database_entry(scsi_qla_host_t *ha, uint16_t fw_ddb_index) { uint32_t mbox_cmd[MBOX_REG_COUNT]; uint32_t mbox_sts[MBOX_REG_COUNT]; memset(&mbox_cmd, 0, sizeof(mbox_cmd)); memset(&mbox_sts, 0, sizeof(mbox_sts)); mbox_cmd[0] = MBOX_CMD_CLEAR_DATABASE_ENTRY; mbox_cmd[1] = fw_ddb_index; if (qla4xxx_mailbox_command(ha, 2, 5, &mbox_cmd[0], &mbox_sts[0]) != QLA_SUCCESS) { QL4PRINT(QLP2, printk("scsi%d: %s: MBOX_CMD_CLEAR_DATABASE_ENTRY " "failed sts %04X index [%d], state %04x\n", ha->host_no, __func__, mbox_sts[0], fw_ddb_index, mbox_sts[4])); return(QLA_ERROR); } return(QLA_SUCCESS); }
/* * qla4xxx_issue_iocb * Issue IOCB using mailbox command * * Input: * ha = adapter state pointer. * buffer = buffer pointer. * phys_addr = physical address of buffer. * size = size of buffer. * TARGET_QUEUE_LOCK must be released. * ADAPTER_STATE_LOCK must be released. * * Returns: * qla2x00 local function return status code. * * Context: * Kernel context. */ uint8_t qla4xxx_issue_iocb(scsi_qla_host_t *ha, uint32_t cmpl_sts_offset, dma_addr_t phys_addr) { uint32_t mbox_cmd[MBOX_REG_COUNT]; uint32_t mbox_sts[MBOX_REG_COUNT]; uint8_t status; memset(&mbox_cmd, 0, sizeof(mbox_cmd)); memset(&mbox_sts, 0, sizeof(mbox_sts)); mbox_cmd[0] = MBOX_CMD_EXECUTE_IOCB_A64; mbox_cmd[1] = cmpl_sts_offset; mbox_cmd[2] = LSDW(phys_addr); mbox_cmd[3] = MSDW(phys_addr); status = qla4xxx_mailbox_command(ha, 4, 1, &mbox_cmd[0], &mbox_sts[0]); if (status != QLA_SUCCESS) { /*EMPTY*/ QL4PRINT(QLP2, printk("qla4xxx_issue_iocb(%d): failed statis 0x%x", ha->host_no, status)); } return status; }
/** * qla4xxx_initialize_fw_cb - initializes firmware control block. * @ha: Pointer to host adapter structure. **/ int qla4xxx_initialize_fw_cb(struct scsi_qla_host * ha) { struct init_fw_ctrl_blk *init_fw_cb; dma_addr_t init_fw_cb_dma; uint32_t mbox_cmd[MBOX_REG_COUNT]; uint32_t mbox_sts[MBOX_REG_COUNT]; int status = QLA_ERROR; init_fw_cb = dma_alloc_coherent(&ha->pdev->dev, sizeof(struct init_fw_ctrl_blk), &init_fw_cb_dma, GFP_KERNEL); if (init_fw_cb == NULL) { DEBUG2(printk("scsi%ld: %s: Unable to alloc init_cb\n", ha->host_no, __func__)); return 10; } memset(init_fw_cb, 0, sizeof(struct init_fw_ctrl_blk)); /* Get Initialize Firmware Control Block. */ memset(&mbox_cmd, 0, sizeof(mbox_cmd)); memset(&mbox_sts, 0, sizeof(mbox_sts)); mbox_cmd[0] = MBOX_CMD_GET_INIT_FW_CTRL_BLOCK; mbox_cmd[2] = LSDW(init_fw_cb_dma); mbox_cmd[3] = MSDW(init_fw_cb_dma); mbox_cmd[4] = sizeof(struct init_fw_ctrl_blk); if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]) != QLA_SUCCESS) { dma_free_coherent(&ha->pdev->dev, sizeof(struct init_fw_ctrl_blk), init_fw_cb, init_fw_cb_dma); return status; } /* Initialize request and response queues. */ qla4xxx_init_rings(ha); /* Fill in the request and response queue information. */ init_fw_cb->pri.rqq_consumer_idx = cpu_to_le16(ha->request_out); init_fw_cb->pri.compq_producer_idx = cpu_to_le16(ha->response_in); init_fw_cb->pri.rqq_len = __constant_cpu_to_le16(REQUEST_QUEUE_DEPTH); init_fw_cb->pri.compq_len = __constant_cpu_to_le16(RESPONSE_QUEUE_DEPTH); init_fw_cb->pri.rqq_addr_lo = cpu_to_le32(LSDW(ha->request_dma)); init_fw_cb->pri.rqq_addr_hi = cpu_to_le32(MSDW(ha->request_dma)); init_fw_cb->pri.compq_addr_lo = cpu_to_le32(LSDW(ha->response_dma)); init_fw_cb->pri.compq_addr_hi = cpu_to_le32(MSDW(ha->response_dma)); init_fw_cb->pri.shdwreg_addr_lo = cpu_to_le32(LSDW(ha->shadow_regs_dma)); init_fw_cb->pri.shdwreg_addr_hi = cpu_to_le32(MSDW(ha->shadow_regs_dma)); /* Set up required options. */ init_fw_cb->pri.fw_options |= __constant_cpu_to_le16(FWOPT_SESSION_MODE | FWOPT_INITIATOR_MODE); init_fw_cb->pri.fw_options &= __constant_cpu_to_le16(~FWOPT_TARGET_MODE); /* Save some info in adapter structure. */ ha->firmware_options = le16_to_cpu(init_fw_cb->pri.fw_options); ha->tcp_options = le16_to_cpu(init_fw_cb->pri.ipv4_tcp_opts); ha->heartbeat_interval = init_fw_cb->pri.hb_interval; memcpy(ha->ip_address, init_fw_cb->pri.ipv4_addr, min(sizeof(ha->ip_address), sizeof(init_fw_cb->pri.ipv4_addr))); memcpy(ha->subnet_mask, init_fw_cb->pri.ipv4_subnet, min(sizeof(ha->subnet_mask), sizeof(init_fw_cb->pri.ipv4_subnet))); memcpy(ha->gateway, init_fw_cb->pri.ipv4_gw_addr, min(sizeof(ha->gateway), sizeof(init_fw_cb->pri.ipv4_gw_addr))); memcpy(ha->name_string, init_fw_cb->pri.iscsi_name, min(sizeof(ha->name_string), sizeof(init_fw_cb->pri.iscsi_name))); /*memcpy(ha->alias, init_fw_cb->Alias, min(sizeof(ha->alias), sizeof(init_fw_cb->Alias)));*/ /* Save Command Line Paramater info */ ha->port_down_retry_count = le16_to_cpu(init_fw_cb->pri.conn_ka_timeout); ha->discovery_wait = ql4xdiscoverywait; /* Send Initialize Firmware Control Block. */ memset(&mbox_cmd, 0, sizeof(mbox_cmd)); memset(&mbox_sts, 0, sizeof(mbox_sts)); mbox_cmd[0] = MBOX_CMD_INITIALIZE_FIRMWARE; mbox_cmd[1] = 0; mbox_cmd[2] = LSDW(init_fw_cb_dma); mbox_cmd[3] = MSDW(init_fw_cb_dma); mbox_cmd[4] = sizeof(struct init_fw_ctrl_blk); if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]) == QLA_SUCCESS) status = QLA_SUCCESS; else { DEBUG2(printk("scsi%ld: %s: MBOX_CMD_INITIALIZE_FIRMWARE " "failed w/ status %04X\n", ha->host_no, __func__, mbox_sts[0])); } dma_free_coherent(&ha->pdev->dev, sizeof(struct init_fw_ctrl_blk), init_fw_cb, init_fw_cb_dma); return status; }