1afaf5a2dSDavid Somayajulu /* 2afaf5a2dSDavid Somayajulu * QLogic iSCSI HBA Driver 37d01d069SVikas Chaudhary * Copyright (c) 2003-2010 QLogic Corporation 4afaf5a2dSDavid Somayajulu * 5afaf5a2dSDavid Somayajulu * See LICENSE.qla4xxx for copyright and licensing details. 6afaf5a2dSDavid Somayajulu */ 7afaf5a2dSDavid Somayajulu 8afaf5a2dSDavid Somayajulu #include "ql4_def.h" 9c0e344c9SDavid C Somayajulu #include "ql4_glbl.h" 10c0e344c9SDavid C Somayajulu #include "ql4_dbg.h" 11c0e344c9SDavid C Somayajulu #include "ql4_inline.h" 12afaf5a2dSDavid Somayajulu 13afaf5a2dSDavid Somayajulu 14afaf5a2dSDavid Somayajulu /** 15afaf5a2dSDavid Somayajulu * qla4xxx_mailbox_command - issues mailbox commands 16afaf5a2dSDavid Somayajulu * @ha: Pointer to host adapter structure. 17afaf5a2dSDavid Somayajulu * @inCount: number of mailbox registers to load. 18afaf5a2dSDavid Somayajulu * @outCount: number of mailbox registers to return. 19afaf5a2dSDavid Somayajulu * @mbx_cmd: data pointer for mailbox in registers. 20afaf5a2dSDavid Somayajulu * @mbx_sts: data pointer for mailbox out registers. 21afaf5a2dSDavid Somayajulu * 2270f23fd6SJustin P. Mattock * This routine issue mailbox commands and waits for completion. 23afaf5a2dSDavid Somayajulu * If outCount is 0, this routine completes successfully WITHOUT waiting 24afaf5a2dSDavid Somayajulu * for the mailbox command to complete. 25afaf5a2dSDavid Somayajulu **/ 26f4f5df23SVikas Chaudhary int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, 27afaf5a2dSDavid Somayajulu uint8_t outCount, uint32_t *mbx_cmd, 28afaf5a2dSDavid Somayajulu uint32_t *mbx_sts) 29afaf5a2dSDavid Somayajulu { 30afaf5a2dSDavid Somayajulu int status = QLA_ERROR; 31afaf5a2dSDavid Somayajulu uint8_t i; 32afaf5a2dSDavid Somayajulu u_long wait_count; 33afaf5a2dSDavid Somayajulu uint32_t intr_status; 34afaf5a2dSDavid Somayajulu unsigned long flags = 0; 3599b53bf5SPrasanna Mumbai uint32_t dev_state; 36afaf5a2dSDavid Somayajulu 37afaf5a2dSDavid Somayajulu /* Make sure that pointers are valid */ 38afaf5a2dSDavid Somayajulu if (!mbx_cmd || !mbx_sts) { 39afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld: %s: Invalid mbx_cmd or mbx_sts " 40afaf5a2dSDavid Somayajulu "pointer\n", ha->host_no, __func__)); 41477ffb9dSDavid C Somayajulu return status; 42477ffb9dSDavid C Somayajulu } 4321033639SNilesh Javali 4499b53bf5SPrasanna Mumbai if (is_qla8022(ha)) { 4599b53bf5SPrasanna Mumbai if (test_bit(AF_FW_RECOVERY, &ha->flags)) { 4699b53bf5SPrasanna Mumbai DEBUG2(ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: " 4799b53bf5SPrasanna Mumbai "prematurely completing mbx cmd as firmware " 4899b53bf5SPrasanna Mumbai "recovery detected\n", ha->host_no, __func__)); 4921033639SNilesh Javali return status; 5021033639SNilesh Javali } 5199b53bf5SPrasanna Mumbai /* Do not send any mbx cmd if h/w is in failed state*/ 5299b53bf5SPrasanna Mumbai qla4_8xxx_idc_lock(ha); 5399b53bf5SPrasanna Mumbai dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE); 5499b53bf5SPrasanna Mumbai qla4_8xxx_idc_unlock(ha); 5599b53bf5SPrasanna Mumbai if (dev_state == QLA82XX_DEV_FAILED) { 5699b53bf5SPrasanna Mumbai ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: H/W is in " 5799b53bf5SPrasanna Mumbai "failed state, do not send any mailbox commands\n", 5899b53bf5SPrasanna Mumbai ha->host_no, __func__); 5999b53bf5SPrasanna Mumbai return status; 6099b53bf5SPrasanna Mumbai } 6199b53bf5SPrasanna Mumbai } 6221033639SNilesh Javali 632232be0dSLalit Chandivade if ((is_aer_supported(ha)) && 642232be0dSLalit Chandivade (test_bit(AF_PCI_CHANNEL_IO_PERM_FAILURE, &ha->flags))) { 652232be0dSLalit Chandivade DEBUG2(printk(KERN_WARNING "scsi%ld: %s: Perm failure on EEH, " 662232be0dSLalit Chandivade "timeout MBX Exiting.\n", ha->host_no, __func__)); 672232be0dSLalit Chandivade return status; 682232be0dSLalit Chandivade } 692232be0dSLalit Chandivade 70477ffb9dSDavid C Somayajulu /* Mailbox code active */ 71477ffb9dSDavid C Somayajulu wait_count = MBOX_TOV * 100; 72477ffb9dSDavid C Somayajulu 73477ffb9dSDavid C Somayajulu while (wait_count--) { 74477ffb9dSDavid C Somayajulu mutex_lock(&ha->mbox_sem); 75477ffb9dSDavid C Somayajulu if (!test_bit(AF_MBOX_COMMAND, &ha->flags)) { 76477ffb9dSDavid C Somayajulu set_bit(AF_MBOX_COMMAND, &ha->flags); 77477ffb9dSDavid C Somayajulu mutex_unlock(&ha->mbox_sem); 78477ffb9dSDavid C Somayajulu break; 79477ffb9dSDavid C Somayajulu } 80477ffb9dSDavid C Somayajulu mutex_unlock(&ha->mbox_sem); 81477ffb9dSDavid C Somayajulu if (!wait_count) { 82477ffb9dSDavid C Somayajulu DEBUG2(printk("scsi%ld: %s: mbox_sem failed\n", 83477ffb9dSDavid C Somayajulu ha->host_no, __func__)); 84477ffb9dSDavid C Somayajulu return status; 85477ffb9dSDavid C Somayajulu } 86477ffb9dSDavid C Somayajulu msleep(10); 87afaf5a2dSDavid Somayajulu } 88afaf5a2dSDavid Somayajulu 89afaf5a2dSDavid Somayajulu spin_lock_irqsave(&ha->hardware_lock, flags); 90f4f5df23SVikas Chaudhary 91afaf5a2dSDavid Somayajulu ha->mbox_status_count = outCount; 92afaf5a2dSDavid Somayajulu for (i = 0; i < outCount; i++) 93afaf5a2dSDavid Somayajulu ha->mbox_status[i] = 0; 94afaf5a2dSDavid Somayajulu 95f4f5df23SVikas Chaudhary if (is_qla8022(ha)) { 96f4f5df23SVikas Chaudhary /* Load all mailbox registers, except mailbox 0. */ 97f4f5df23SVikas Chaudhary DEBUG5( 98f4f5df23SVikas Chaudhary printk("scsi%ld: %s: Cmd ", ha->host_no, __func__); 99f4f5df23SVikas Chaudhary for (i = 0; i < inCount; i++) 100f4f5df23SVikas Chaudhary printk("mb%d=%04x ", i, mbx_cmd[i]); 101f4f5df23SVikas Chaudhary printk("\n")); 102f4f5df23SVikas Chaudhary 103f4f5df23SVikas Chaudhary for (i = 1; i < inCount; i++) 104f4f5df23SVikas Chaudhary writel(mbx_cmd[i], &ha->qla4_8xxx_reg->mailbox_in[i]); 105f4f5df23SVikas Chaudhary writel(mbx_cmd[0], &ha->qla4_8xxx_reg->mailbox_in[0]); 106f4f5df23SVikas Chaudhary readl(&ha->qla4_8xxx_reg->mailbox_in[0]); 107f4f5df23SVikas Chaudhary writel(HINT_MBX_INT_PENDING, &ha->qla4_8xxx_reg->hint); 108f4f5df23SVikas Chaudhary } else { 109afaf5a2dSDavid Somayajulu /* Load all mailbox registers, except mailbox 0. */ 110afaf5a2dSDavid Somayajulu for (i = 1; i < inCount; i++) 111afaf5a2dSDavid Somayajulu writel(mbx_cmd[i], &ha->reg->mailbox[i]); 112afaf5a2dSDavid Somayajulu 113afaf5a2dSDavid Somayajulu /* Wakeup firmware */ 114afaf5a2dSDavid Somayajulu writel(mbx_cmd[0], &ha->reg->mailbox[0]); 115afaf5a2dSDavid Somayajulu readl(&ha->reg->mailbox[0]); 116afaf5a2dSDavid Somayajulu writel(set_rmask(CSR_INTR_RISC), &ha->reg->ctrl_status); 117afaf5a2dSDavid Somayajulu readl(&ha->reg->ctrl_status); 118f4f5df23SVikas Chaudhary } 119f4f5df23SVikas Chaudhary 120afaf5a2dSDavid Somayajulu spin_unlock_irqrestore(&ha->hardware_lock, flags); 121afaf5a2dSDavid Somayajulu 122afaf5a2dSDavid Somayajulu /* Wait for completion */ 123afaf5a2dSDavid Somayajulu 124afaf5a2dSDavid Somayajulu /* 125afaf5a2dSDavid Somayajulu * If we don't want status, don't wait for the mailbox command to 126afaf5a2dSDavid Somayajulu * complete. For example, MBOX_CMD_RESET_FW doesn't return status, 127afaf5a2dSDavid Somayajulu * you must poll the inbound Interrupt Mask for completion. 128afaf5a2dSDavid Somayajulu */ 129afaf5a2dSDavid Somayajulu if (outCount == 0) { 130afaf5a2dSDavid Somayajulu status = QLA_SUCCESS; 131afaf5a2dSDavid Somayajulu goto mbox_exit; 132afaf5a2dSDavid Somayajulu } 133f4f5df23SVikas Chaudhary 134f4f5df23SVikas Chaudhary /* 135f4f5df23SVikas Chaudhary * Wait for completion: Poll or completion queue 136f4f5df23SVikas Chaudhary */ 137f4f5df23SVikas Chaudhary if (test_bit(AF_IRQ_ATTACHED, &ha->flags) && 138f4f5df23SVikas Chaudhary test_bit(AF_INTERRUPTS_ON, &ha->flags) && 139f4f5df23SVikas Chaudhary test_bit(AF_ONLINE, &ha->flags) && 1407eece5a0SKaren Higgins !test_bit(AF_HA_REMOVAL, &ha->flags)) { 141f4f5df23SVikas Chaudhary /* Do not poll for completion. Use completion queue */ 142f4f5df23SVikas Chaudhary set_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags); 143f4f5df23SVikas Chaudhary wait_for_completion_timeout(&ha->mbx_intr_comp, MBOX_TOV * HZ); 144f4f5df23SVikas Chaudhary clear_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags); 145f4f5df23SVikas Chaudhary } else { 146f4f5df23SVikas Chaudhary /* Poll for command to complete */ 147afaf5a2dSDavid Somayajulu wait_count = jiffies + MBOX_TOV * HZ; 148afaf5a2dSDavid Somayajulu while (test_bit(AF_MBOX_COMMAND_DONE, &ha->flags) == 0) { 149afaf5a2dSDavid Somayajulu if (time_after_eq(jiffies, wait_count)) 150afaf5a2dSDavid Somayajulu break; 1512232be0dSLalit Chandivade 152afaf5a2dSDavid Somayajulu /* 153afaf5a2dSDavid Somayajulu * Service the interrupt. 154afaf5a2dSDavid Somayajulu * The ISR will save the mailbox status registers 155afaf5a2dSDavid Somayajulu * to a temporary storage location in the adapter 156afaf5a2dSDavid Somayajulu * structure. 157afaf5a2dSDavid Somayajulu */ 158f4f5df23SVikas Chaudhary 159f4f5df23SVikas Chaudhary spin_lock_irqsave(&ha->hardware_lock, flags); 160f4f5df23SVikas Chaudhary if (is_qla8022(ha)) { 161f4f5df23SVikas Chaudhary intr_status = 162f4f5df23SVikas Chaudhary readl(&ha->qla4_8xxx_reg->host_int); 163f4f5df23SVikas Chaudhary if (intr_status & ISRX_82XX_RISC_INT) { 164afaf5a2dSDavid Somayajulu ha->mbox_status_count = outCount; 165f4f5df23SVikas Chaudhary intr_status = 166f4f5df23SVikas Chaudhary readl(&ha->qla4_8xxx_reg->host_status); 167f4f5df23SVikas Chaudhary ha->isp_ops->interrupt_service_routine( 168f4f5df23SVikas Chaudhary ha, intr_status); 169f4f5df23SVikas Chaudhary if (test_bit(AF_INTERRUPTS_ON, 170f4f5df23SVikas Chaudhary &ha->flags) && 171f4f5df23SVikas Chaudhary test_bit(AF_INTx_ENABLED, 172f4f5df23SVikas Chaudhary &ha->flags)) 173f4f5df23SVikas Chaudhary qla4_8xxx_wr_32(ha, 174f4f5df23SVikas Chaudhary ha->nx_legacy_intr.tgt_mask_reg, 175f4f5df23SVikas Chaudhary 0xfbff); 176f4f5df23SVikas Chaudhary } 177f4f5df23SVikas Chaudhary } else { 178f4f5df23SVikas Chaudhary intr_status = readl(&ha->reg->ctrl_status); 179f4f5df23SVikas Chaudhary if (intr_status & INTR_PENDING) { 180f4f5df23SVikas Chaudhary /* 181f4f5df23SVikas Chaudhary * Service the interrupt. 182f4f5df23SVikas Chaudhary * The ISR will save the mailbox status 183f4f5df23SVikas Chaudhary * registers to a temporary storage 184f4f5df23SVikas Chaudhary * location in the adapter structure. 185f4f5df23SVikas Chaudhary */ 186f4f5df23SVikas Chaudhary ha->mbox_status_count = outCount; 187f4f5df23SVikas Chaudhary ha->isp_ops->interrupt_service_routine( 188f4f5df23SVikas Chaudhary ha, intr_status); 189f4f5df23SVikas Chaudhary } 190afaf5a2dSDavid Somayajulu } 191afaf5a2dSDavid Somayajulu spin_unlock_irqrestore(&ha->hardware_lock, flags); 192afaf5a2dSDavid Somayajulu msleep(10); 193afaf5a2dSDavid Somayajulu } 194f4f5df23SVikas Chaudhary } 195afaf5a2dSDavid Somayajulu 196afaf5a2dSDavid Somayajulu /* Check for mailbox timeout. */ 197afaf5a2dSDavid Somayajulu if (!test_bit(AF_MBOX_COMMAND_DONE, &ha->flags)) { 19821033639SNilesh Javali if (is_qla8022(ha) && 19921033639SNilesh Javali test_bit(AF_FW_RECOVERY, &ha->flags)) { 20021033639SNilesh Javali DEBUG2(ql4_printk(KERN_INFO, ha, 20121033639SNilesh Javali "scsi%ld: %s: prematurely completing mbx cmd as " 20221033639SNilesh Javali "firmware recovery detected\n", 20321033639SNilesh Javali ha->host_no, __func__)); 20421033639SNilesh Javali goto mbox_exit; 20521033639SNilesh Javali } 206afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld: Mailbox Cmd 0x%08X timed out ...," 207afaf5a2dSDavid Somayajulu " Scheduling Adapter Reset\n", ha->host_no, 208afaf5a2dSDavid Somayajulu mbx_cmd[0])); 209afaf5a2dSDavid Somayajulu ha->mailbox_timeout_count++; 210afaf5a2dSDavid Somayajulu mbx_sts[0] = (-1); 211afaf5a2dSDavid Somayajulu set_bit(DPC_RESET_HA, &ha->dpc_flags); 212afaf5a2dSDavid Somayajulu goto mbox_exit; 213afaf5a2dSDavid Somayajulu } 214afaf5a2dSDavid Somayajulu 215afaf5a2dSDavid Somayajulu /* 216afaf5a2dSDavid Somayajulu * Copy the mailbox out registers to the caller's mailbox in/out 217afaf5a2dSDavid Somayajulu * structure. 218afaf5a2dSDavid Somayajulu */ 219afaf5a2dSDavid Somayajulu spin_lock_irqsave(&ha->hardware_lock, flags); 220afaf5a2dSDavid Somayajulu for (i = 0; i < outCount; i++) 221afaf5a2dSDavid Somayajulu mbx_sts[i] = ha->mbox_status[i]; 222afaf5a2dSDavid Somayajulu 223afaf5a2dSDavid Somayajulu /* Set return status and error flags (if applicable). */ 224afaf5a2dSDavid Somayajulu switch (ha->mbox_status[0]) { 225afaf5a2dSDavid Somayajulu case MBOX_STS_COMMAND_COMPLETE: 226afaf5a2dSDavid Somayajulu status = QLA_SUCCESS; 227afaf5a2dSDavid Somayajulu break; 228afaf5a2dSDavid Somayajulu 229afaf5a2dSDavid Somayajulu case MBOX_STS_INTERMEDIATE_COMPLETION: 230afaf5a2dSDavid Somayajulu status = QLA_SUCCESS; 231afaf5a2dSDavid Somayajulu break; 232afaf5a2dSDavid Somayajulu 233afaf5a2dSDavid Somayajulu case MBOX_STS_BUSY: 234afaf5a2dSDavid Somayajulu DEBUG2( printk("scsi%ld: %s: Cmd = %08X, ISP BUSY\n", 235afaf5a2dSDavid Somayajulu ha->host_no, __func__, mbx_cmd[0])); 236afaf5a2dSDavid Somayajulu ha->mailbox_timeout_count++; 237afaf5a2dSDavid Somayajulu break; 238afaf5a2dSDavid Somayajulu 239afaf5a2dSDavid Somayajulu default: 240afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld: %s: **** FAILED, cmd = %08X, " 241afaf5a2dSDavid Somayajulu "sts = %08X ****\n", ha->host_no, __func__, 242afaf5a2dSDavid Somayajulu mbx_cmd[0], mbx_sts[0])); 243afaf5a2dSDavid Somayajulu break; 244afaf5a2dSDavid Somayajulu } 245afaf5a2dSDavid Somayajulu spin_unlock_irqrestore(&ha->hardware_lock, flags); 246afaf5a2dSDavid Somayajulu 247afaf5a2dSDavid Somayajulu mbox_exit: 248477ffb9dSDavid C Somayajulu mutex_lock(&ha->mbox_sem); 249afaf5a2dSDavid Somayajulu clear_bit(AF_MBOX_COMMAND, &ha->flags); 250afaf5a2dSDavid Somayajulu mutex_unlock(&ha->mbox_sem); 251477ffb9dSDavid C Somayajulu clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags); 252afaf5a2dSDavid Somayajulu 253afaf5a2dSDavid Somayajulu return status; 254afaf5a2dSDavid Somayajulu } 255afaf5a2dSDavid Somayajulu 25621033639SNilesh Javali void qla4xxx_mailbox_premature_completion(struct scsi_qla_host *ha) 25721033639SNilesh Javali { 25821033639SNilesh Javali set_bit(AF_FW_RECOVERY, &ha->flags); 25921033639SNilesh Javali ql4_printk(KERN_INFO, ha, "scsi%ld: %s: set FW RECOVERY!\n", 26021033639SNilesh Javali ha->host_no, __func__); 26121033639SNilesh Javali 26221033639SNilesh Javali if (test_bit(AF_MBOX_COMMAND, &ha->flags)) { 26321033639SNilesh Javali if (test_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags)) { 26421033639SNilesh Javali complete(&ha->mbx_intr_comp); 26521033639SNilesh Javali ql4_printk(KERN_INFO, ha, "scsi%ld: %s: Due to fw " 26621033639SNilesh Javali "recovery, doing premature completion of " 26721033639SNilesh Javali "mbx cmd\n", ha->host_no, __func__); 26821033639SNilesh Javali 26921033639SNilesh Javali } else { 27021033639SNilesh Javali set_bit(AF_MBOX_COMMAND_DONE, &ha->flags); 27121033639SNilesh Javali ql4_printk(KERN_INFO, ha, "scsi%ld: %s: Due to fw " 27221033639SNilesh Javali "recovery, doing premature completion of " 27321033639SNilesh Javali "polling mbx cmd\n", ha->host_no, __func__); 27421033639SNilesh Javali } 27521033639SNilesh Javali } 27621033639SNilesh Javali } 27721033639SNilesh Javali 278f4f5df23SVikas Chaudhary static uint8_t 2792a49a78eSVikas Chaudhary qla4xxx_set_ifcb(struct scsi_qla_host *ha, uint32_t *mbox_cmd, 2802a49a78eSVikas Chaudhary uint32_t *mbox_sts, dma_addr_t init_fw_cb_dma) 2812a49a78eSVikas Chaudhary { 2822a49a78eSVikas Chaudhary memset(mbox_cmd, 0, sizeof(mbox_cmd[0]) * MBOX_REG_COUNT); 2832a49a78eSVikas Chaudhary memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT); 2842657c800SShyam Sundar 2852657c800SShyam Sundar if (is_qla8022(ha)) 2862657c800SShyam Sundar qla4_8xxx_wr_32(ha, ha->nx_db_wr_ptr, 0); 2872657c800SShyam Sundar 2882a49a78eSVikas Chaudhary mbox_cmd[0] = MBOX_CMD_INITIALIZE_FIRMWARE; 2892a49a78eSVikas Chaudhary mbox_cmd[1] = 0; 2902a49a78eSVikas Chaudhary mbox_cmd[2] = LSDW(init_fw_cb_dma); 2912a49a78eSVikas Chaudhary mbox_cmd[3] = MSDW(init_fw_cb_dma); 2922a49a78eSVikas Chaudhary mbox_cmd[4] = sizeof(struct addr_ctrl_blk); 2932a49a78eSVikas Chaudhary mbox_cmd[5] = (IFCB_VER_MAX << 8) | IFCB_VER_MIN; 2942a49a78eSVikas Chaudhary 2952a49a78eSVikas Chaudhary if (qla4xxx_mailbox_command(ha, 6, 6, mbox_cmd, mbox_sts) != 2962a49a78eSVikas Chaudhary QLA_SUCCESS) { 2972a49a78eSVikas Chaudhary DEBUG2(printk(KERN_WARNING "scsi%ld: %s: " 2982a49a78eSVikas Chaudhary "MBOX_CMD_INITIALIZE_FIRMWARE" 2992a49a78eSVikas Chaudhary " failed w/ status %04X\n", 3002a49a78eSVikas Chaudhary ha->host_no, __func__, mbox_sts[0])); 3012a49a78eSVikas Chaudhary return QLA_ERROR; 3022a49a78eSVikas Chaudhary } 3032a49a78eSVikas Chaudhary return QLA_SUCCESS; 3042a49a78eSVikas Chaudhary } 3052a49a78eSVikas Chaudhary 306d00efe3fSMike Christie uint8_t 3072a49a78eSVikas Chaudhary qla4xxx_get_ifcb(struct scsi_qla_host *ha, uint32_t *mbox_cmd, 3082a49a78eSVikas Chaudhary uint32_t *mbox_sts, dma_addr_t init_fw_cb_dma) 3092a49a78eSVikas Chaudhary { 3102a49a78eSVikas Chaudhary memset(mbox_cmd, 0, sizeof(mbox_cmd[0]) * MBOX_REG_COUNT); 3112a49a78eSVikas Chaudhary memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT); 3122a49a78eSVikas Chaudhary mbox_cmd[0] = MBOX_CMD_GET_INIT_FW_CTRL_BLOCK; 3132a49a78eSVikas Chaudhary mbox_cmd[2] = LSDW(init_fw_cb_dma); 3142a49a78eSVikas Chaudhary mbox_cmd[3] = MSDW(init_fw_cb_dma); 3152a49a78eSVikas Chaudhary mbox_cmd[4] = sizeof(struct addr_ctrl_blk); 3162a49a78eSVikas Chaudhary 3172a49a78eSVikas Chaudhary if (qla4xxx_mailbox_command(ha, 5, 5, mbox_cmd, mbox_sts) != 3182a49a78eSVikas Chaudhary QLA_SUCCESS) { 3192a49a78eSVikas Chaudhary DEBUG2(printk(KERN_WARNING "scsi%ld: %s: " 3202a49a78eSVikas Chaudhary "MBOX_CMD_GET_INIT_FW_CTRL_BLOCK" 3212a49a78eSVikas Chaudhary " failed w/ status %04X\n", 3222a49a78eSVikas Chaudhary ha->host_no, __func__, mbox_sts[0])); 3232a49a78eSVikas Chaudhary return QLA_ERROR; 3242a49a78eSVikas Chaudhary } 3252a49a78eSVikas Chaudhary return QLA_SUCCESS; 3262a49a78eSVikas Chaudhary } 3272a49a78eSVikas Chaudhary 328f4f5df23SVikas Chaudhary static void 3292a49a78eSVikas Chaudhary qla4xxx_update_local_ip(struct scsi_qla_host *ha, 3302a49a78eSVikas Chaudhary struct addr_ctrl_blk *init_fw_cb) 3312a49a78eSVikas Chaudhary { 3322bab08fcSVikas Chaudhary ha->ip_config.tcp_options = le16_to_cpu(init_fw_cb->ipv4_tcp_opts); 3332bab08fcSVikas Chaudhary ha->ip_config.ipv4_options = le16_to_cpu(init_fw_cb->ipv4_ip_opts); 3342bab08fcSVikas Chaudhary ha->ip_config.ipv4_addr_state = 3352bab08fcSVikas Chaudhary le16_to_cpu(init_fw_cb->ipv4_addr_state); 336943c157bSVikas Chaudhary ha->ip_config.eth_mtu_size = 337943c157bSVikas Chaudhary le16_to_cpu(init_fw_cb->eth_mtu_size); 3382ada7fc5SVikas Chaudhary ha->ip_config.ipv4_port = le16_to_cpu(init_fw_cb->ipv4_port); 3392bab08fcSVikas Chaudhary 3402bab08fcSVikas Chaudhary if (ha->acb_version == ACB_SUPPORTED) { 3412bab08fcSVikas Chaudhary ha->ip_config.ipv6_options = le16_to_cpu(init_fw_cb->ipv6_opts); 3422bab08fcSVikas Chaudhary ha->ip_config.ipv6_addl_options = 3432bab08fcSVikas Chaudhary le16_to_cpu(init_fw_cb->ipv6_addtl_opts); 3442bab08fcSVikas Chaudhary } 3452bab08fcSVikas Chaudhary 3462a49a78eSVikas Chaudhary /* Save IPv4 Address Info */ 3472bab08fcSVikas Chaudhary memcpy(ha->ip_config.ip_address, init_fw_cb->ipv4_addr, 3482bab08fcSVikas Chaudhary min(sizeof(ha->ip_config.ip_address), 3492bab08fcSVikas Chaudhary sizeof(init_fw_cb->ipv4_addr))); 3502bab08fcSVikas Chaudhary memcpy(ha->ip_config.subnet_mask, init_fw_cb->ipv4_subnet, 3512bab08fcSVikas Chaudhary min(sizeof(ha->ip_config.subnet_mask), 3522bab08fcSVikas Chaudhary sizeof(init_fw_cb->ipv4_subnet))); 3532bab08fcSVikas Chaudhary memcpy(ha->ip_config.gateway, init_fw_cb->ipv4_gw_addr, 3542bab08fcSVikas Chaudhary min(sizeof(ha->ip_config.gateway), 3552bab08fcSVikas Chaudhary sizeof(init_fw_cb->ipv4_gw_addr))); 3562a49a78eSVikas Chaudhary 3576ac73e8cSVikas Chaudhary ha->ip_config.ipv4_vlan_tag = be16_to_cpu(init_fw_cb->ipv4_vlan_tag); 3586ac73e8cSVikas Chaudhary 3592a49a78eSVikas Chaudhary if (is_ipv6_enabled(ha)) { 3602a49a78eSVikas Chaudhary /* Save IPv6 Address */ 3612bab08fcSVikas Chaudhary ha->ip_config.ipv6_link_local_state = 3622bab08fcSVikas Chaudhary le16_to_cpu(init_fw_cb->ipv6_lnk_lcl_addr_state); 3632bab08fcSVikas Chaudhary ha->ip_config.ipv6_addr0_state = 3642bab08fcSVikas Chaudhary le16_to_cpu(init_fw_cb->ipv6_addr0_state); 3652bab08fcSVikas Chaudhary ha->ip_config.ipv6_addr1_state = 3662bab08fcSVikas Chaudhary le16_to_cpu(init_fw_cb->ipv6_addr1_state); 3672bab08fcSVikas Chaudhary ha->ip_config.ipv6_default_router_state = 3682bab08fcSVikas Chaudhary le16_to_cpu(init_fw_cb->ipv6_dflt_rtr_state); 3692bab08fcSVikas Chaudhary ha->ip_config.ipv6_link_local_addr.in6_u.u6_addr8[0] = 0xFE; 3702bab08fcSVikas Chaudhary ha->ip_config.ipv6_link_local_addr.in6_u.u6_addr8[1] = 0x80; 3712a49a78eSVikas Chaudhary 3722bab08fcSVikas Chaudhary memcpy(&ha->ip_config.ipv6_link_local_addr.in6_u.u6_addr8[8], 3732a49a78eSVikas Chaudhary init_fw_cb->ipv6_if_id, 3742bab08fcSVikas Chaudhary min(sizeof(ha->ip_config.ipv6_link_local_addr)/2, 3752a49a78eSVikas Chaudhary sizeof(init_fw_cb->ipv6_if_id))); 3762bab08fcSVikas Chaudhary memcpy(&ha->ip_config.ipv6_addr0, init_fw_cb->ipv6_addr0, 3772bab08fcSVikas Chaudhary min(sizeof(ha->ip_config.ipv6_addr0), 3782a49a78eSVikas Chaudhary sizeof(init_fw_cb->ipv6_addr0))); 3792bab08fcSVikas Chaudhary memcpy(&ha->ip_config.ipv6_addr1, init_fw_cb->ipv6_addr1, 3802bab08fcSVikas Chaudhary min(sizeof(ha->ip_config.ipv6_addr1), 3812a49a78eSVikas Chaudhary sizeof(init_fw_cb->ipv6_addr1))); 3822bab08fcSVikas Chaudhary memcpy(&ha->ip_config.ipv6_default_router_addr, 3832a49a78eSVikas Chaudhary init_fw_cb->ipv6_dflt_rtr_addr, 3842bab08fcSVikas Chaudhary min(sizeof(ha->ip_config.ipv6_default_router_addr), 3852a49a78eSVikas Chaudhary sizeof(init_fw_cb->ipv6_dflt_rtr_addr))); 3866ac73e8cSVikas Chaudhary ha->ip_config.ipv6_vlan_tag = 3876ac73e8cSVikas Chaudhary be16_to_cpu(init_fw_cb->ipv6_vlan_tag); 3882ada7fc5SVikas Chaudhary ha->ip_config.ipv6_port = le16_to_cpu(init_fw_cb->ipv6_port); 3892a49a78eSVikas Chaudhary } 3902a49a78eSVikas Chaudhary } 3912a49a78eSVikas Chaudhary 392d00efe3fSMike Christie uint8_t 3932a49a78eSVikas Chaudhary qla4xxx_update_local_ifcb(struct scsi_qla_host *ha, 3942a49a78eSVikas Chaudhary uint32_t *mbox_cmd, 3952a49a78eSVikas Chaudhary uint32_t *mbox_sts, 3962a49a78eSVikas Chaudhary struct addr_ctrl_blk *init_fw_cb, 3972a49a78eSVikas Chaudhary dma_addr_t init_fw_cb_dma) 3982a49a78eSVikas Chaudhary { 3992a49a78eSVikas Chaudhary if (qla4xxx_get_ifcb(ha, mbox_cmd, mbox_sts, init_fw_cb_dma) 4002a49a78eSVikas Chaudhary != QLA_SUCCESS) { 4012a49a78eSVikas Chaudhary DEBUG2(printk(KERN_WARNING 4022a49a78eSVikas Chaudhary "scsi%ld: %s: Failed to get init_fw_ctrl_blk\n", 4032a49a78eSVikas Chaudhary ha->host_no, __func__)); 4042a49a78eSVikas Chaudhary return QLA_ERROR; 4052a49a78eSVikas Chaudhary } 4062a49a78eSVikas Chaudhary 4072a49a78eSVikas Chaudhary DEBUG2(qla4xxx_dump_buffer(init_fw_cb, sizeof(struct addr_ctrl_blk))); 4082a49a78eSVikas Chaudhary 4092a49a78eSVikas Chaudhary /* Save some info in adapter structure. */ 4102a49a78eSVikas Chaudhary ha->acb_version = init_fw_cb->acb_version; 4112a49a78eSVikas Chaudhary ha->firmware_options = le16_to_cpu(init_fw_cb->fw_options); 4122a49a78eSVikas Chaudhary ha->heartbeat_interval = init_fw_cb->hb_interval; 4132a49a78eSVikas Chaudhary memcpy(ha->name_string, init_fw_cb->iscsi_name, 4142a49a78eSVikas Chaudhary min(sizeof(ha->name_string), 4152a49a78eSVikas Chaudhary sizeof(init_fw_cb->iscsi_name))); 4162a49a78eSVikas Chaudhary /*memcpy(ha->alias, init_fw_cb->Alias, 4172a49a78eSVikas Chaudhary min(sizeof(ha->alias), sizeof(init_fw_cb->Alias)));*/ 4182a49a78eSVikas Chaudhary 4192a49a78eSVikas Chaudhary qla4xxx_update_local_ip(ha, init_fw_cb); 4202a49a78eSVikas Chaudhary 4212a49a78eSVikas Chaudhary return QLA_SUCCESS; 4222a49a78eSVikas Chaudhary } 4232a49a78eSVikas Chaudhary 424afaf5a2dSDavid Somayajulu /** 425afaf5a2dSDavid Somayajulu * qla4xxx_initialize_fw_cb - initializes firmware control block. 426afaf5a2dSDavid Somayajulu * @ha: Pointer to host adapter structure. 427afaf5a2dSDavid Somayajulu **/ 428afaf5a2dSDavid Somayajulu int qla4xxx_initialize_fw_cb(struct scsi_qla_host * ha) 429afaf5a2dSDavid Somayajulu { 4302a49a78eSVikas Chaudhary struct addr_ctrl_blk *init_fw_cb; 431afaf5a2dSDavid Somayajulu dma_addr_t init_fw_cb_dma; 432afaf5a2dSDavid Somayajulu uint32_t mbox_cmd[MBOX_REG_COUNT]; 433afaf5a2dSDavid Somayajulu uint32_t mbox_sts[MBOX_REG_COUNT]; 434afaf5a2dSDavid Somayajulu int status = QLA_ERROR; 435afaf5a2dSDavid Somayajulu 436afaf5a2dSDavid Somayajulu init_fw_cb = dma_alloc_coherent(&ha->pdev->dev, 4372a49a78eSVikas Chaudhary sizeof(struct addr_ctrl_blk), 438afaf5a2dSDavid Somayajulu &init_fw_cb_dma, GFP_KERNEL); 439afaf5a2dSDavid Somayajulu if (init_fw_cb == NULL) { 440afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld: %s: Unable to alloc init_cb\n", 441afaf5a2dSDavid Somayajulu ha->host_no, __func__)); 442beabe7c1SPrasanna Mumbai goto exit_init_fw_cb_no_free; 443afaf5a2dSDavid Somayajulu } 4442a49a78eSVikas Chaudhary memset(init_fw_cb, 0, sizeof(struct addr_ctrl_blk)); 445afaf5a2dSDavid Somayajulu 446afaf5a2dSDavid Somayajulu /* Get Initialize Firmware Control Block. */ 447afaf5a2dSDavid Somayajulu memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 448afaf5a2dSDavid Somayajulu memset(&mbox_sts, 0, sizeof(mbox_sts)); 449c0e344c9SDavid C Somayajulu 4502a49a78eSVikas Chaudhary if (qla4xxx_get_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb_dma) != 451afaf5a2dSDavid Somayajulu QLA_SUCCESS) { 452afaf5a2dSDavid Somayajulu dma_free_coherent(&ha->pdev->dev, 4532a49a78eSVikas Chaudhary sizeof(struct addr_ctrl_blk), 454afaf5a2dSDavid Somayajulu init_fw_cb, init_fw_cb_dma); 4552a49a78eSVikas Chaudhary goto exit_init_fw_cb; 456afaf5a2dSDavid Somayajulu } 457afaf5a2dSDavid Somayajulu 458afaf5a2dSDavid Somayajulu /* Initialize request and response queues. */ 459afaf5a2dSDavid Somayajulu qla4xxx_init_rings(ha); 460afaf5a2dSDavid Somayajulu 461afaf5a2dSDavid Somayajulu /* Fill in the request and response queue information. */ 4622a49a78eSVikas Chaudhary init_fw_cb->rqq_consumer_idx = cpu_to_le16(ha->request_out); 4632a49a78eSVikas Chaudhary init_fw_cb->compq_producer_idx = cpu_to_le16(ha->response_in); 4642a49a78eSVikas Chaudhary init_fw_cb->rqq_len = __constant_cpu_to_le16(REQUEST_QUEUE_DEPTH); 4652a49a78eSVikas Chaudhary init_fw_cb->compq_len = __constant_cpu_to_le16(RESPONSE_QUEUE_DEPTH); 4662a49a78eSVikas Chaudhary init_fw_cb->rqq_addr_lo = cpu_to_le32(LSDW(ha->request_dma)); 4672a49a78eSVikas Chaudhary init_fw_cb->rqq_addr_hi = cpu_to_le32(MSDW(ha->request_dma)); 4682a49a78eSVikas Chaudhary init_fw_cb->compq_addr_lo = cpu_to_le32(LSDW(ha->response_dma)); 4692a49a78eSVikas Chaudhary init_fw_cb->compq_addr_hi = cpu_to_le32(MSDW(ha->response_dma)); 4702a49a78eSVikas Chaudhary init_fw_cb->shdwreg_addr_lo = cpu_to_le32(LSDW(ha->shadow_regs_dma)); 4712a49a78eSVikas Chaudhary init_fw_cb->shdwreg_addr_hi = cpu_to_le32(MSDW(ha->shadow_regs_dma)); 472afaf5a2dSDavid Somayajulu 473afaf5a2dSDavid Somayajulu /* Set up required options. */ 4742a49a78eSVikas Chaudhary init_fw_cb->fw_options |= 475afaf5a2dSDavid Somayajulu __constant_cpu_to_le16(FWOPT_SESSION_MODE | 476afaf5a2dSDavid Somayajulu FWOPT_INITIATOR_MODE); 4772657c800SShyam Sundar 4782657c800SShyam Sundar if (is_qla8022(ha)) 4792657c800SShyam Sundar init_fw_cb->fw_options |= 4802657c800SShyam Sundar __constant_cpu_to_le16(FWOPT_ENABLE_CRBDB); 4812657c800SShyam Sundar 4822a49a78eSVikas Chaudhary init_fw_cb->fw_options &= __constant_cpu_to_le16(~FWOPT_TARGET_MODE); 483afaf5a2dSDavid Somayajulu 484d32cee3cSPrasanna Mumbai init_fw_cb->add_fw_options = 0; 485d32cee3cSPrasanna Mumbai init_fw_cb->add_fw_options |= 486b3a271a9SManish Rangankar __constant_cpu_to_le16(ADFWOPT_SERIALIZE_TASK_MGMT); 487b3a271a9SManish Rangankar init_fw_cb->add_fw_options |= 488b3a271a9SManish Rangankar __constant_cpu_to_le16(ADFWOPT_AUTOCONN_DISABLE); 489d32cee3cSPrasanna Mumbai 4902a49a78eSVikas Chaudhary if (qla4xxx_set_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb_dma) 4912a49a78eSVikas Chaudhary != QLA_SUCCESS) { 4922a49a78eSVikas Chaudhary DEBUG2(printk(KERN_WARNING 4932a49a78eSVikas Chaudhary "scsi%ld: %s: Failed to set init_fw_ctrl_blk\n", 4942a49a78eSVikas Chaudhary ha->host_no, __func__)); 4952a49a78eSVikas Chaudhary goto exit_init_fw_cb; 496afaf5a2dSDavid Somayajulu } 4972a49a78eSVikas Chaudhary 4982a49a78eSVikas Chaudhary if (qla4xxx_update_local_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], 4992a49a78eSVikas Chaudhary init_fw_cb, init_fw_cb_dma) != QLA_SUCCESS) { 5002a49a78eSVikas Chaudhary DEBUG2(printk("scsi%ld: %s: Failed to update local ifcb\n", 5012a49a78eSVikas Chaudhary ha->host_no, __func__)); 5022a49a78eSVikas Chaudhary goto exit_init_fw_cb; 5032a49a78eSVikas Chaudhary } 5042a49a78eSVikas Chaudhary status = QLA_SUCCESS; 5052a49a78eSVikas Chaudhary 5062a49a78eSVikas Chaudhary exit_init_fw_cb: 5072a49a78eSVikas Chaudhary dma_free_coherent(&ha->pdev->dev, sizeof(struct addr_ctrl_blk), 508afaf5a2dSDavid Somayajulu init_fw_cb, init_fw_cb_dma); 509beabe7c1SPrasanna Mumbai exit_init_fw_cb_no_free: 510afaf5a2dSDavid Somayajulu return status; 511afaf5a2dSDavid Somayajulu } 512afaf5a2dSDavid Somayajulu 513afaf5a2dSDavid Somayajulu /** 514afaf5a2dSDavid Somayajulu * qla4xxx_get_dhcp_ip_address - gets HBA ip address via DHCP 515afaf5a2dSDavid Somayajulu * @ha: Pointer to host adapter structure. 516afaf5a2dSDavid Somayajulu **/ 517afaf5a2dSDavid Somayajulu int qla4xxx_get_dhcp_ip_address(struct scsi_qla_host * ha) 518afaf5a2dSDavid Somayajulu { 5192a49a78eSVikas Chaudhary struct addr_ctrl_blk *init_fw_cb; 520afaf5a2dSDavid Somayajulu dma_addr_t init_fw_cb_dma; 521afaf5a2dSDavid Somayajulu uint32_t mbox_cmd[MBOX_REG_COUNT]; 522afaf5a2dSDavid Somayajulu uint32_t mbox_sts[MBOX_REG_COUNT]; 523afaf5a2dSDavid Somayajulu 524afaf5a2dSDavid Somayajulu init_fw_cb = dma_alloc_coherent(&ha->pdev->dev, 5252a49a78eSVikas Chaudhary sizeof(struct addr_ctrl_blk), 526afaf5a2dSDavid Somayajulu &init_fw_cb_dma, GFP_KERNEL); 527afaf5a2dSDavid Somayajulu if (init_fw_cb == NULL) { 528afaf5a2dSDavid Somayajulu printk("scsi%ld: %s: Unable to alloc init_cb\n", ha->host_no, 529afaf5a2dSDavid Somayajulu __func__); 530beabe7c1SPrasanna Mumbai return QLA_ERROR; 531afaf5a2dSDavid Somayajulu } 532afaf5a2dSDavid Somayajulu 533afaf5a2dSDavid Somayajulu /* Get Initialize Firmware Control Block. */ 5342a49a78eSVikas Chaudhary memset(init_fw_cb, 0, sizeof(struct addr_ctrl_blk)); 5352a49a78eSVikas Chaudhary if (qla4xxx_get_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb_dma) != 536afaf5a2dSDavid Somayajulu QLA_SUCCESS) { 537afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld: %s: Failed to get init_fw_ctrl_blk\n", 538afaf5a2dSDavid Somayajulu ha->host_no, __func__)); 539afaf5a2dSDavid Somayajulu dma_free_coherent(&ha->pdev->dev, 5402a49a78eSVikas Chaudhary sizeof(struct addr_ctrl_blk), 541afaf5a2dSDavid Somayajulu init_fw_cb, init_fw_cb_dma); 542afaf5a2dSDavid Somayajulu return QLA_ERROR; 543afaf5a2dSDavid Somayajulu } 544afaf5a2dSDavid Somayajulu 545afaf5a2dSDavid Somayajulu /* Save IP Address. */ 5462a49a78eSVikas Chaudhary qla4xxx_update_local_ip(ha, init_fw_cb); 5472a49a78eSVikas Chaudhary dma_free_coherent(&ha->pdev->dev, sizeof(struct addr_ctrl_blk), 548afaf5a2dSDavid Somayajulu init_fw_cb, init_fw_cb_dma); 549afaf5a2dSDavid Somayajulu 550afaf5a2dSDavid Somayajulu return QLA_SUCCESS; 551afaf5a2dSDavid Somayajulu } 552afaf5a2dSDavid Somayajulu 553afaf5a2dSDavid Somayajulu /** 554afaf5a2dSDavid Somayajulu * qla4xxx_get_firmware_state - gets firmware state of HBA 555afaf5a2dSDavid Somayajulu * @ha: Pointer to host adapter structure. 556afaf5a2dSDavid Somayajulu **/ 557afaf5a2dSDavid Somayajulu int qla4xxx_get_firmware_state(struct scsi_qla_host * ha) 558afaf5a2dSDavid Somayajulu { 559afaf5a2dSDavid Somayajulu uint32_t mbox_cmd[MBOX_REG_COUNT]; 560afaf5a2dSDavid Somayajulu uint32_t mbox_sts[MBOX_REG_COUNT]; 561afaf5a2dSDavid Somayajulu 562afaf5a2dSDavid Somayajulu /* Get firmware version */ 563afaf5a2dSDavid Somayajulu memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 564afaf5a2dSDavid Somayajulu memset(&mbox_sts, 0, sizeof(mbox_sts)); 565c0e344c9SDavid C Somayajulu 566afaf5a2dSDavid Somayajulu mbox_cmd[0] = MBOX_CMD_GET_FW_STATE; 567c0e344c9SDavid C Somayajulu 568c0e344c9SDavid C Somayajulu if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 4, &mbox_cmd[0], &mbox_sts[0]) != 569afaf5a2dSDavid Somayajulu QLA_SUCCESS) { 570afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_FW_STATE failed w/ " 571afaf5a2dSDavid Somayajulu "status %04X\n", ha->host_no, __func__, 572afaf5a2dSDavid Somayajulu mbox_sts[0])); 573afaf5a2dSDavid Somayajulu return QLA_ERROR; 574afaf5a2dSDavid Somayajulu } 575afaf5a2dSDavid Somayajulu ha->firmware_state = mbox_sts[1]; 576afaf5a2dSDavid Somayajulu ha->board_id = mbox_sts[2]; 577afaf5a2dSDavid Somayajulu ha->addl_fw_state = mbox_sts[3]; 578afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld: %s firmware_state=0x%x\n", 579afaf5a2dSDavid Somayajulu ha->host_no, __func__, ha->firmware_state);) 580afaf5a2dSDavid Somayajulu 581afaf5a2dSDavid Somayajulu return QLA_SUCCESS; 582afaf5a2dSDavid Somayajulu } 583afaf5a2dSDavid Somayajulu 584afaf5a2dSDavid Somayajulu /** 585afaf5a2dSDavid Somayajulu * qla4xxx_get_firmware_status - retrieves firmware status 586afaf5a2dSDavid Somayajulu * @ha: Pointer to host adapter structure. 587afaf5a2dSDavid Somayajulu **/ 588afaf5a2dSDavid Somayajulu int qla4xxx_get_firmware_status(struct scsi_qla_host * ha) 589afaf5a2dSDavid Somayajulu { 590afaf5a2dSDavid Somayajulu uint32_t mbox_cmd[MBOX_REG_COUNT]; 591afaf5a2dSDavid Somayajulu uint32_t mbox_sts[MBOX_REG_COUNT]; 592afaf5a2dSDavid Somayajulu 593afaf5a2dSDavid Somayajulu /* Get firmware version */ 594afaf5a2dSDavid Somayajulu memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 595afaf5a2dSDavid Somayajulu memset(&mbox_sts, 0, sizeof(mbox_sts)); 596c0e344c9SDavid C Somayajulu 597afaf5a2dSDavid Somayajulu mbox_cmd[0] = MBOX_CMD_GET_FW_STATUS; 598c0e344c9SDavid C Somayajulu 599c0e344c9SDavid C Somayajulu if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 3, &mbox_cmd[0], &mbox_sts[0]) != 600afaf5a2dSDavid Somayajulu QLA_SUCCESS) { 601afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_FW_STATUS failed w/ " 602afaf5a2dSDavid Somayajulu "status %04X\n", ha->host_no, __func__, 603afaf5a2dSDavid Somayajulu mbox_sts[0])); 604afaf5a2dSDavid Somayajulu return QLA_ERROR; 605afaf5a2dSDavid Somayajulu } 606f4f5df23SVikas Chaudhary 607f4f5df23SVikas Chaudhary ql4_printk(KERN_INFO, ha, "%ld firmare IOCBs available (%d).\n", 608f581a3f7SVikas Chaudhary ha->host_no, mbox_sts[2]); 609f4f5df23SVikas Chaudhary 610afaf5a2dSDavid Somayajulu return QLA_SUCCESS; 611afaf5a2dSDavid Somayajulu } 612afaf5a2dSDavid Somayajulu 613afaf5a2dSDavid Somayajulu /** 614afaf5a2dSDavid Somayajulu * qla4xxx_get_fwddb_entry - retrieves firmware ddb entry 615afaf5a2dSDavid Somayajulu * @ha: Pointer to host adapter structure. 616afaf5a2dSDavid Somayajulu * @fw_ddb_index: Firmware's device database index 617afaf5a2dSDavid Somayajulu * @fw_ddb_entry: Pointer to firmware's device database entry structure 618afaf5a2dSDavid Somayajulu * @num_valid_ddb_entries: Pointer to number of valid ddb entries 619afaf5a2dSDavid Somayajulu * @next_ddb_index: Pointer to next valid device database index 620afaf5a2dSDavid Somayajulu * @fw_ddb_device_state: Pointer to device state 621afaf5a2dSDavid Somayajulu **/ 622afaf5a2dSDavid Somayajulu int qla4xxx_get_fwddb_entry(struct scsi_qla_host *ha, 623afaf5a2dSDavid Somayajulu uint16_t fw_ddb_index, 624afaf5a2dSDavid Somayajulu struct dev_db_entry *fw_ddb_entry, 625afaf5a2dSDavid Somayajulu dma_addr_t fw_ddb_entry_dma, 626afaf5a2dSDavid Somayajulu uint32_t *num_valid_ddb_entries, 627afaf5a2dSDavid Somayajulu uint32_t *next_ddb_index, 628afaf5a2dSDavid Somayajulu uint32_t *fw_ddb_device_state, 629afaf5a2dSDavid Somayajulu uint32_t *conn_err_detail, 630afaf5a2dSDavid Somayajulu uint16_t *tcp_source_port_num, 631afaf5a2dSDavid Somayajulu uint16_t *connection_id) 632afaf5a2dSDavid Somayajulu { 633afaf5a2dSDavid Somayajulu int status = QLA_ERROR; 6342a49a78eSVikas Chaudhary uint16_t options; 635afaf5a2dSDavid Somayajulu uint32_t mbox_cmd[MBOX_REG_COUNT]; 636afaf5a2dSDavid Somayajulu uint32_t mbox_sts[MBOX_REG_COUNT]; 637afaf5a2dSDavid Somayajulu 638afaf5a2dSDavid Somayajulu /* Make sure the device index is valid */ 639afaf5a2dSDavid Somayajulu if (fw_ddb_index >= MAX_DDB_ENTRIES) { 640f4f5df23SVikas Chaudhary DEBUG2(printk("scsi%ld: %s: ddb [%d] out of range.\n", 641afaf5a2dSDavid Somayajulu ha->host_no, __func__, fw_ddb_index)); 642afaf5a2dSDavid Somayajulu goto exit_get_fwddb; 643afaf5a2dSDavid Somayajulu } 644afaf5a2dSDavid Somayajulu memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 645afaf5a2dSDavid Somayajulu memset(&mbox_sts, 0, sizeof(mbox_sts)); 646c0e344c9SDavid C Somayajulu 647afaf5a2dSDavid Somayajulu mbox_cmd[0] = MBOX_CMD_GET_DATABASE_ENTRY; 648afaf5a2dSDavid Somayajulu mbox_cmd[1] = (uint32_t) fw_ddb_index; 649afaf5a2dSDavid Somayajulu mbox_cmd[2] = LSDW(fw_ddb_entry_dma); 650afaf5a2dSDavid Somayajulu mbox_cmd[3] = MSDW(fw_ddb_entry_dma); 651c0e344c9SDavid C Somayajulu mbox_cmd[4] = sizeof(struct dev_db_entry); 652c0e344c9SDavid C Somayajulu 653c0e344c9SDavid C Somayajulu if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 7, &mbox_cmd[0], &mbox_sts[0]) == 654afaf5a2dSDavid Somayajulu QLA_ERROR) { 655afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_DATABASE_ENTRY failed" 656afaf5a2dSDavid Somayajulu " with status 0x%04X\n", ha->host_no, __func__, 657afaf5a2dSDavid Somayajulu mbox_sts[0])); 658afaf5a2dSDavid Somayajulu goto exit_get_fwddb; 659afaf5a2dSDavid Somayajulu } 660afaf5a2dSDavid Somayajulu if (fw_ddb_index != mbox_sts[1]) { 661f4f5df23SVikas Chaudhary DEBUG2(printk("scsi%ld: %s: ddb mismatch [%d] != [%d].\n", 662afaf5a2dSDavid Somayajulu ha->host_no, __func__, fw_ddb_index, 663afaf5a2dSDavid Somayajulu mbox_sts[1])); 664afaf5a2dSDavid Somayajulu goto exit_get_fwddb; 665afaf5a2dSDavid Somayajulu } 666afaf5a2dSDavid Somayajulu if (fw_ddb_entry) { 6672a49a78eSVikas Chaudhary options = le16_to_cpu(fw_ddb_entry->options); 6682a49a78eSVikas Chaudhary if (options & DDB_OPT_IPV6_DEVICE) { 669c2660df3SVikas Chaudhary ql4_printk(KERN_INFO, ha, "%s: DDB[%d] MB0 %04x Tot %d " 6702a49a78eSVikas Chaudhary "Next %d State %04x ConnErr %08x %pI6 " 6712a49a78eSVikas Chaudhary ":%04d \"%s\"\n", __func__, fw_ddb_index, 6722a49a78eSVikas Chaudhary mbox_sts[0], mbox_sts[2], mbox_sts[3], 6732a49a78eSVikas Chaudhary mbox_sts[4], mbox_sts[5], 6742a49a78eSVikas Chaudhary fw_ddb_entry->ip_addr, 675c0e344c9SDavid C Somayajulu le16_to_cpu(fw_ddb_entry->port), 676c0e344c9SDavid C Somayajulu fw_ddb_entry->iscsi_name); 6772a49a78eSVikas Chaudhary } else { 678c2660df3SVikas Chaudhary ql4_printk(KERN_INFO, ha, "%s: DDB[%d] MB0 %04x Tot %d " 6792a49a78eSVikas Chaudhary "Next %d State %04x ConnErr %08x %pI4 " 6802a49a78eSVikas Chaudhary ":%04d \"%s\"\n", __func__, fw_ddb_index, 6812a49a78eSVikas Chaudhary mbox_sts[0], mbox_sts[2], mbox_sts[3], 6822a49a78eSVikas Chaudhary mbox_sts[4], mbox_sts[5], 6832a49a78eSVikas Chaudhary fw_ddb_entry->ip_addr, 6842a49a78eSVikas Chaudhary le16_to_cpu(fw_ddb_entry->port), 6852a49a78eSVikas Chaudhary fw_ddb_entry->iscsi_name); 6862a49a78eSVikas Chaudhary } 687afaf5a2dSDavid Somayajulu } 688afaf5a2dSDavid Somayajulu if (num_valid_ddb_entries) 689afaf5a2dSDavid Somayajulu *num_valid_ddb_entries = mbox_sts[2]; 690afaf5a2dSDavid Somayajulu if (next_ddb_index) 691afaf5a2dSDavid Somayajulu *next_ddb_index = mbox_sts[3]; 692afaf5a2dSDavid Somayajulu if (fw_ddb_device_state) 693afaf5a2dSDavid Somayajulu *fw_ddb_device_state = mbox_sts[4]; 694afaf5a2dSDavid Somayajulu 695afaf5a2dSDavid Somayajulu /* 696afaf5a2dSDavid Somayajulu * RA: This mailbox has been changed to pass connection error and 697afaf5a2dSDavid Somayajulu * details. Its true for ISP4010 as per Version E - Not sure when it 698afaf5a2dSDavid Somayajulu * was changed. Get the time2wait from the fw_dd_entry field : 699afaf5a2dSDavid Somayajulu * default_time2wait which we call it as minTime2Wait DEV_DB_ENTRY 700afaf5a2dSDavid Somayajulu * struct. 701afaf5a2dSDavid Somayajulu */ 702afaf5a2dSDavid Somayajulu if (conn_err_detail) 703afaf5a2dSDavid Somayajulu *conn_err_detail = mbox_sts[5]; 704afaf5a2dSDavid Somayajulu if (tcp_source_port_num) 7051482338fSRandy Dunlap *tcp_source_port_num = (uint16_t) (mbox_sts[6] >> 16); 706afaf5a2dSDavid Somayajulu if (connection_id) 707afaf5a2dSDavid Somayajulu *connection_id = (uint16_t) mbox_sts[6] & 0x00FF; 708afaf5a2dSDavid Somayajulu status = QLA_SUCCESS; 709afaf5a2dSDavid Somayajulu 710afaf5a2dSDavid Somayajulu exit_get_fwddb: 711afaf5a2dSDavid Somayajulu return status; 712afaf5a2dSDavid Somayajulu } 713afaf5a2dSDavid Somayajulu 714b3a271a9SManish Rangankar int qla4xxx_conn_open(struct scsi_qla_host *ha, uint16_t fw_ddb_index) 715b3a271a9SManish Rangankar { 716b3a271a9SManish Rangankar uint32_t mbox_cmd[MBOX_REG_COUNT]; 717b3a271a9SManish Rangankar uint32_t mbox_sts[MBOX_REG_COUNT]; 718b3a271a9SManish Rangankar int status; 719b3a271a9SManish Rangankar 720b3a271a9SManish Rangankar memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 721b3a271a9SManish Rangankar memset(&mbox_sts, 0, sizeof(mbox_sts)); 722b3a271a9SManish Rangankar 723b3a271a9SManish Rangankar mbox_cmd[0] = MBOX_CMD_CONN_OPEN; 724b3a271a9SManish Rangankar mbox_cmd[1] = fw_ddb_index; 725b3a271a9SManish Rangankar 726b3a271a9SManish Rangankar status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 2, &mbox_cmd[0], 727b3a271a9SManish Rangankar &mbox_sts[0]); 728b3a271a9SManish Rangankar DEBUG2(ql4_printk(KERN_INFO, ha, 729b3a271a9SManish Rangankar "%s: status = %d mbx0 = 0x%x mbx1 = 0x%x\n", 730b3a271a9SManish Rangankar __func__, status, mbox_sts[0], mbox_sts[1])); 731b3a271a9SManish Rangankar return status; 732b3a271a9SManish Rangankar } 733b3a271a9SManish Rangankar 734afaf5a2dSDavid Somayajulu /** 735afaf5a2dSDavid Somayajulu * qla4xxx_set_fwddb_entry - sets a ddb entry. 736afaf5a2dSDavid Somayajulu * @ha: Pointer to host adapter structure. 737afaf5a2dSDavid Somayajulu * @fw_ddb_index: Firmware's device database index 738b3a271a9SManish Rangankar * @fw_ddb_entry_dma: dma address of ddb entry 739b3a271a9SManish Rangankar * @mbx_sts: mailbox 0 to be returned or NULL 740afaf5a2dSDavid Somayajulu * 741afaf5a2dSDavid Somayajulu * This routine initializes or updates the adapter's device database 742b3a271a9SManish Rangankar * entry for the specified device. 743afaf5a2dSDavid Somayajulu **/ 744afaf5a2dSDavid Somayajulu int qla4xxx_set_ddb_entry(struct scsi_qla_host * ha, uint16_t fw_ddb_index, 745b3a271a9SManish Rangankar dma_addr_t fw_ddb_entry_dma, uint32_t *mbx_sts) 746afaf5a2dSDavid Somayajulu { 747afaf5a2dSDavid Somayajulu uint32_t mbox_cmd[MBOX_REG_COUNT]; 748afaf5a2dSDavid Somayajulu uint32_t mbox_sts[MBOX_REG_COUNT]; 749f4f5df23SVikas Chaudhary int status; 750afaf5a2dSDavid Somayajulu 751afaf5a2dSDavid Somayajulu /* Do not wait for completion. The firmware will send us an 752afaf5a2dSDavid Somayajulu * ASTS_DATABASE_CHANGED (0x8014) to notify us of the login status. 753afaf5a2dSDavid Somayajulu */ 754afaf5a2dSDavid Somayajulu memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 755afaf5a2dSDavid Somayajulu memset(&mbox_sts, 0, sizeof(mbox_sts)); 756afaf5a2dSDavid Somayajulu 757afaf5a2dSDavid Somayajulu mbox_cmd[0] = MBOX_CMD_SET_DATABASE_ENTRY; 758afaf5a2dSDavid Somayajulu mbox_cmd[1] = (uint32_t) fw_ddb_index; 759afaf5a2dSDavid Somayajulu mbox_cmd[2] = LSDW(fw_ddb_entry_dma); 760afaf5a2dSDavid Somayajulu mbox_cmd[3] = MSDW(fw_ddb_entry_dma); 761c0e344c9SDavid C Somayajulu mbox_cmd[4] = sizeof(struct dev_db_entry); 762c0e344c9SDavid C Somayajulu 763f4f5df23SVikas Chaudhary status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], 764f4f5df23SVikas Chaudhary &mbox_sts[0]); 765b3a271a9SManish Rangankar if (mbx_sts) 766b3a271a9SManish Rangankar *mbx_sts = mbox_sts[0]; 767f4f5df23SVikas Chaudhary DEBUG2(printk("scsi%ld: %s: status=%d mbx0=0x%x mbx4=0x%x\n", 768f4f5df23SVikas Chaudhary ha->host_no, __func__, status, mbox_sts[0], mbox_sts[4]);) 769f4f5df23SVikas Chaudhary 770f4f5df23SVikas Chaudhary return status; 771afaf5a2dSDavid Somayajulu } 772afaf5a2dSDavid Somayajulu 773b3a271a9SManish Rangankar int qla4xxx_session_logout_ddb(struct scsi_qla_host *ha, 774b3a271a9SManish Rangankar struct ddb_entry *ddb_entry, int options) 775b3a271a9SManish Rangankar { 776b3a271a9SManish Rangankar int status; 777b3a271a9SManish Rangankar uint32_t mbox_cmd[MBOX_REG_COUNT]; 778b3a271a9SManish Rangankar uint32_t mbox_sts[MBOX_REG_COUNT]; 779b3a271a9SManish Rangankar 780b3a271a9SManish Rangankar memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 781b3a271a9SManish Rangankar memset(&mbox_sts, 0, sizeof(mbox_sts)); 782b3a271a9SManish Rangankar 783b3a271a9SManish Rangankar mbox_cmd[0] = MBOX_CMD_CONN_CLOSE_SESS_LOGOUT; 784b3a271a9SManish Rangankar mbox_cmd[1] = ddb_entry->fw_ddb_index; 785b3a271a9SManish Rangankar mbox_cmd[3] = options; 786b3a271a9SManish Rangankar 787b3a271a9SManish Rangankar status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 2, &mbox_cmd[0], 788b3a271a9SManish Rangankar &mbox_sts[0]); 789b3a271a9SManish Rangankar if (status != QLA_SUCCESS) { 790b3a271a9SManish Rangankar DEBUG2(ql4_printk(KERN_INFO, ha, 791b3a271a9SManish Rangankar "%s: MBOX_CMD_CONN_CLOSE_SESS_LOGOUT " 792b3a271a9SManish Rangankar "failed sts %04X %04X", __func__, 793b3a271a9SManish Rangankar mbox_sts[0], mbox_sts[1])); 794b3a271a9SManish Rangankar } 795b3a271a9SManish Rangankar 796b3a271a9SManish Rangankar return status; 797b3a271a9SManish Rangankar } 798b3a271a9SManish Rangankar 799afaf5a2dSDavid Somayajulu /** 800afaf5a2dSDavid Somayajulu * qla4xxx_get_crash_record - retrieves crash record. 801afaf5a2dSDavid Somayajulu * @ha: Pointer to host adapter structure. 802afaf5a2dSDavid Somayajulu * 803afaf5a2dSDavid Somayajulu * This routine retrieves a crash record from the QLA4010 after an 8002h aen. 804afaf5a2dSDavid Somayajulu **/ 805afaf5a2dSDavid Somayajulu void qla4xxx_get_crash_record(struct scsi_qla_host * ha) 806afaf5a2dSDavid Somayajulu { 807afaf5a2dSDavid Somayajulu uint32_t mbox_cmd[MBOX_REG_COUNT]; 808afaf5a2dSDavid Somayajulu uint32_t mbox_sts[MBOX_REG_COUNT]; 809afaf5a2dSDavid Somayajulu struct crash_record *crash_record = NULL; 810afaf5a2dSDavid Somayajulu dma_addr_t crash_record_dma = 0; 811afaf5a2dSDavid Somayajulu uint32_t crash_record_size = 0; 812c0e344c9SDavid C Somayajulu 813afaf5a2dSDavid Somayajulu memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 814afaf5a2dSDavid Somayajulu memset(&mbox_sts, 0, sizeof(mbox_cmd)); 815afaf5a2dSDavid Somayajulu 816afaf5a2dSDavid Somayajulu /* Get size of crash record. */ 817afaf5a2dSDavid Somayajulu mbox_cmd[0] = MBOX_CMD_GET_CRASH_RECORD; 818c0e344c9SDavid C Somayajulu 819c0e344c9SDavid C Somayajulu if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) != 820afaf5a2dSDavid Somayajulu QLA_SUCCESS) { 821afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld: %s: ERROR: Unable to retrieve size!\n", 822afaf5a2dSDavid Somayajulu ha->host_no, __func__)); 823afaf5a2dSDavid Somayajulu goto exit_get_crash_record; 824afaf5a2dSDavid Somayajulu } 825afaf5a2dSDavid Somayajulu crash_record_size = mbox_sts[4]; 826afaf5a2dSDavid Somayajulu if (crash_record_size == 0) { 827afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld: %s: ERROR: Crash record size is 0!\n", 828afaf5a2dSDavid Somayajulu ha->host_no, __func__)); 829afaf5a2dSDavid Somayajulu goto exit_get_crash_record; 830afaf5a2dSDavid Somayajulu } 831afaf5a2dSDavid Somayajulu 832afaf5a2dSDavid Somayajulu /* Alloc Memory for Crash Record. */ 833afaf5a2dSDavid Somayajulu crash_record = dma_alloc_coherent(&ha->pdev->dev, crash_record_size, 834afaf5a2dSDavid Somayajulu &crash_record_dma, GFP_KERNEL); 835afaf5a2dSDavid Somayajulu if (crash_record == NULL) 836afaf5a2dSDavid Somayajulu goto exit_get_crash_record; 837afaf5a2dSDavid Somayajulu 838afaf5a2dSDavid Somayajulu /* Get Crash Record. */ 839c0e344c9SDavid C Somayajulu memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 840c0e344c9SDavid C Somayajulu memset(&mbox_sts, 0, sizeof(mbox_cmd)); 841c0e344c9SDavid C Somayajulu 842afaf5a2dSDavid Somayajulu mbox_cmd[0] = MBOX_CMD_GET_CRASH_RECORD; 843afaf5a2dSDavid Somayajulu mbox_cmd[2] = LSDW(crash_record_dma); 844afaf5a2dSDavid Somayajulu mbox_cmd[3] = MSDW(crash_record_dma); 845afaf5a2dSDavid Somayajulu mbox_cmd[4] = crash_record_size; 846c0e344c9SDavid C Somayajulu 847c0e344c9SDavid C Somayajulu if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) != 848afaf5a2dSDavid Somayajulu QLA_SUCCESS) 849afaf5a2dSDavid Somayajulu goto exit_get_crash_record; 850afaf5a2dSDavid Somayajulu 851afaf5a2dSDavid Somayajulu /* Dump Crash Record. */ 852afaf5a2dSDavid Somayajulu 853afaf5a2dSDavid Somayajulu exit_get_crash_record: 854afaf5a2dSDavid Somayajulu if (crash_record) 855afaf5a2dSDavid Somayajulu dma_free_coherent(&ha->pdev->dev, crash_record_size, 856afaf5a2dSDavid Somayajulu crash_record, crash_record_dma); 857afaf5a2dSDavid Somayajulu } 858afaf5a2dSDavid Somayajulu 859afaf5a2dSDavid Somayajulu /** 860afaf5a2dSDavid Somayajulu * qla4xxx_get_conn_event_log - retrieves connection event log 861afaf5a2dSDavid Somayajulu * @ha: Pointer to host adapter structure. 862afaf5a2dSDavid Somayajulu **/ 863afaf5a2dSDavid Somayajulu void qla4xxx_get_conn_event_log(struct scsi_qla_host * ha) 864afaf5a2dSDavid Somayajulu { 865afaf5a2dSDavid Somayajulu uint32_t mbox_cmd[MBOX_REG_COUNT]; 866afaf5a2dSDavid Somayajulu uint32_t mbox_sts[MBOX_REG_COUNT]; 867afaf5a2dSDavid Somayajulu struct conn_event_log_entry *event_log = NULL; 868afaf5a2dSDavid Somayajulu dma_addr_t event_log_dma = 0; 869afaf5a2dSDavid Somayajulu uint32_t event_log_size = 0; 870afaf5a2dSDavid Somayajulu uint32_t num_valid_entries; 871afaf5a2dSDavid Somayajulu uint32_t oldest_entry = 0; 872afaf5a2dSDavid Somayajulu uint32_t max_event_log_entries; 873afaf5a2dSDavid Somayajulu uint8_t i; 874afaf5a2dSDavid Somayajulu 875afaf5a2dSDavid Somayajulu 876afaf5a2dSDavid Somayajulu memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 877afaf5a2dSDavid Somayajulu memset(&mbox_sts, 0, sizeof(mbox_cmd)); 878afaf5a2dSDavid Somayajulu 879afaf5a2dSDavid Somayajulu /* Get size of crash record. */ 880afaf5a2dSDavid Somayajulu mbox_cmd[0] = MBOX_CMD_GET_CONN_EVENT_LOG; 881c0e344c9SDavid C Somayajulu 882c0e344c9SDavid C Somayajulu if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) != 883afaf5a2dSDavid Somayajulu QLA_SUCCESS) 884afaf5a2dSDavid Somayajulu goto exit_get_event_log; 885afaf5a2dSDavid Somayajulu 886afaf5a2dSDavid Somayajulu event_log_size = mbox_sts[4]; 887afaf5a2dSDavid Somayajulu if (event_log_size == 0) 888afaf5a2dSDavid Somayajulu goto exit_get_event_log; 889afaf5a2dSDavid Somayajulu 890afaf5a2dSDavid Somayajulu /* Alloc Memory for Crash Record. */ 891afaf5a2dSDavid Somayajulu event_log = dma_alloc_coherent(&ha->pdev->dev, event_log_size, 892afaf5a2dSDavid Somayajulu &event_log_dma, GFP_KERNEL); 893afaf5a2dSDavid Somayajulu if (event_log == NULL) 894afaf5a2dSDavid Somayajulu goto exit_get_event_log; 895afaf5a2dSDavid Somayajulu 896afaf5a2dSDavid Somayajulu /* Get Crash Record. */ 897c0e344c9SDavid C Somayajulu memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 898c0e344c9SDavid C Somayajulu memset(&mbox_sts, 0, sizeof(mbox_cmd)); 899c0e344c9SDavid C Somayajulu 900afaf5a2dSDavid Somayajulu mbox_cmd[0] = MBOX_CMD_GET_CONN_EVENT_LOG; 901afaf5a2dSDavid Somayajulu mbox_cmd[2] = LSDW(event_log_dma); 902afaf5a2dSDavid Somayajulu mbox_cmd[3] = MSDW(event_log_dma); 903c0e344c9SDavid C Somayajulu 904c0e344c9SDavid C Somayajulu if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) != 905afaf5a2dSDavid Somayajulu QLA_SUCCESS) { 906afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld: %s: ERROR: Unable to retrieve event " 907afaf5a2dSDavid Somayajulu "log!\n", ha->host_no, __func__)); 908afaf5a2dSDavid Somayajulu goto exit_get_event_log; 909afaf5a2dSDavid Somayajulu } 910afaf5a2dSDavid Somayajulu 911afaf5a2dSDavid Somayajulu /* Dump Event Log. */ 912afaf5a2dSDavid Somayajulu num_valid_entries = mbox_sts[1]; 913afaf5a2dSDavid Somayajulu 914afaf5a2dSDavid Somayajulu max_event_log_entries = event_log_size / 915afaf5a2dSDavid Somayajulu sizeof(struct conn_event_log_entry); 916afaf5a2dSDavid Somayajulu 917afaf5a2dSDavid Somayajulu if (num_valid_entries > max_event_log_entries) 918afaf5a2dSDavid Somayajulu oldest_entry = num_valid_entries % max_event_log_entries; 919afaf5a2dSDavid Somayajulu 920afaf5a2dSDavid Somayajulu DEBUG3(printk("scsi%ld: Connection Event Log Dump (%d entries):\n", 921afaf5a2dSDavid Somayajulu ha->host_no, num_valid_entries)); 922afaf5a2dSDavid Somayajulu 92311010fecSAndrew Vasquez if (ql4xextended_error_logging == 3) { 924afaf5a2dSDavid Somayajulu if (oldest_entry == 0) { 925afaf5a2dSDavid Somayajulu /* Circular Buffer has not wrapped around */ 926afaf5a2dSDavid Somayajulu for (i=0; i < num_valid_entries; i++) { 927afaf5a2dSDavid Somayajulu qla4xxx_dump_buffer((uint8_t *)event_log+ 928afaf5a2dSDavid Somayajulu (i*sizeof(*event_log)), 929afaf5a2dSDavid Somayajulu sizeof(*event_log)); 930afaf5a2dSDavid Somayajulu } 931afaf5a2dSDavid Somayajulu } 932afaf5a2dSDavid Somayajulu else { 933afaf5a2dSDavid Somayajulu /* Circular Buffer has wrapped around - 934afaf5a2dSDavid Somayajulu * display accordingly*/ 935afaf5a2dSDavid Somayajulu for (i=oldest_entry; i < max_event_log_entries; i++) { 936afaf5a2dSDavid Somayajulu qla4xxx_dump_buffer((uint8_t *)event_log+ 937afaf5a2dSDavid Somayajulu (i*sizeof(*event_log)), 938afaf5a2dSDavid Somayajulu sizeof(*event_log)); 939afaf5a2dSDavid Somayajulu } 940afaf5a2dSDavid Somayajulu for (i=0; i < oldest_entry; i++) { 941afaf5a2dSDavid Somayajulu qla4xxx_dump_buffer((uint8_t *)event_log+ 942afaf5a2dSDavid Somayajulu (i*sizeof(*event_log)), 943afaf5a2dSDavid Somayajulu sizeof(*event_log)); 944afaf5a2dSDavid Somayajulu } 945afaf5a2dSDavid Somayajulu } 946afaf5a2dSDavid Somayajulu } 947afaf5a2dSDavid Somayajulu 948afaf5a2dSDavid Somayajulu exit_get_event_log: 949afaf5a2dSDavid Somayajulu if (event_log) 950afaf5a2dSDavid Somayajulu dma_free_coherent(&ha->pdev->dev, event_log_size, event_log, 951afaf5a2dSDavid Somayajulu event_log_dma); 952afaf5a2dSDavid Somayajulu } 953afaf5a2dSDavid Somayajulu 954afaf5a2dSDavid Somayajulu /** 95509a0f719SVikas Chaudhary * qla4xxx_abort_task - issues Abort Task 95609a0f719SVikas Chaudhary * @ha: Pointer to host adapter structure. 95709a0f719SVikas Chaudhary * @srb: Pointer to srb entry 95809a0f719SVikas Chaudhary * 95909a0f719SVikas Chaudhary * This routine performs a LUN RESET on the specified target/lun. 96009a0f719SVikas Chaudhary * The caller must ensure that the ddb_entry and lun_entry pointers 96109a0f719SVikas Chaudhary * are valid before calling this routine. 96209a0f719SVikas Chaudhary **/ 96309a0f719SVikas Chaudhary int qla4xxx_abort_task(struct scsi_qla_host *ha, struct srb *srb) 96409a0f719SVikas Chaudhary { 96509a0f719SVikas Chaudhary uint32_t mbox_cmd[MBOX_REG_COUNT]; 96609a0f719SVikas Chaudhary uint32_t mbox_sts[MBOX_REG_COUNT]; 96709a0f719SVikas Chaudhary struct scsi_cmnd *cmd = srb->cmd; 96809a0f719SVikas Chaudhary int status = QLA_SUCCESS; 96909a0f719SVikas Chaudhary unsigned long flags = 0; 97009a0f719SVikas Chaudhary uint32_t index; 97109a0f719SVikas Chaudhary 97209a0f719SVikas Chaudhary /* 97309a0f719SVikas Chaudhary * Send abort task command to ISP, so that the ISP will return 97409a0f719SVikas Chaudhary * request with ABORT status 97509a0f719SVikas Chaudhary */ 97609a0f719SVikas Chaudhary memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 97709a0f719SVikas Chaudhary memset(&mbox_sts, 0, sizeof(mbox_sts)); 97809a0f719SVikas Chaudhary 97909a0f719SVikas Chaudhary spin_lock_irqsave(&ha->hardware_lock, flags); 98009a0f719SVikas Chaudhary index = (unsigned long)(unsigned char *)cmd->host_scribble; 98109a0f719SVikas Chaudhary spin_unlock_irqrestore(&ha->hardware_lock, flags); 98209a0f719SVikas Chaudhary 98309a0f719SVikas Chaudhary /* Firmware already posted completion on response queue */ 98409a0f719SVikas Chaudhary if (index == MAX_SRBS) 98509a0f719SVikas Chaudhary return status; 98609a0f719SVikas Chaudhary 98709a0f719SVikas Chaudhary mbox_cmd[0] = MBOX_CMD_ABORT_TASK; 9886790d4feSKaren Higgins mbox_cmd[1] = srb->ddb->fw_ddb_index; 98909a0f719SVikas Chaudhary mbox_cmd[2] = index; 99009a0f719SVikas Chaudhary /* Immediate Command Enable */ 99109a0f719SVikas Chaudhary mbox_cmd[5] = 0x01; 99209a0f719SVikas Chaudhary 99309a0f719SVikas Chaudhary qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], 99409a0f719SVikas Chaudhary &mbox_sts[0]); 99509a0f719SVikas Chaudhary if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE) { 99609a0f719SVikas Chaudhary status = QLA_ERROR; 99709a0f719SVikas Chaudhary 99809a0f719SVikas Chaudhary DEBUG2(printk(KERN_WARNING "scsi%ld:%d:%d: abort task FAILED: " 99909a0f719SVikas Chaudhary "mbx0=%04X, mb1=%04X, mb2=%04X, mb3=%04X, mb4=%04X\n", 100009a0f719SVikas Chaudhary ha->host_no, cmd->device->id, cmd->device->lun, mbox_sts[0], 100109a0f719SVikas Chaudhary mbox_sts[1], mbox_sts[2], mbox_sts[3], mbox_sts[4])); 100209a0f719SVikas Chaudhary } 100309a0f719SVikas Chaudhary 100409a0f719SVikas Chaudhary return status; 100509a0f719SVikas Chaudhary } 100609a0f719SVikas Chaudhary 100709a0f719SVikas Chaudhary /** 1008afaf5a2dSDavid Somayajulu * qla4xxx_reset_lun - issues LUN Reset 1009afaf5a2dSDavid Somayajulu * @ha: Pointer to host adapter structure. 1010f4f5df23SVikas Chaudhary * @ddb_entry: Pointer to device database entry 1011f4f5df23SVikas Chaudhary * @lun: lun number 1012afaf5a2dSDavid Somayajulu * 1013afaf5a2dSDavid Somayajulu * This routine performs a LUN RESET on the specified target/lun. 1014afaf5a2dSDavid Somayajulu * The caller must ensure that the ddb_entry and lun_entry pointers 1015afaf5a2dSDavid Somayajulu * are valid before calling this routine. 1016afaf5a2dSDavid Somayajulu **/ 1017afaf5a2dSDavid Somayajulu int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry, 1018afaf5a2dSDavid Somayajulu int lun) 1019afaf5a2dSDavid Somayajulu { 1020afaf5a2dSDavid Somayajulu uint32_t mbox_cmd[MBOX_REG_COUNT]; 1021afaf5a2dSDavid Somayajulu uint32_t mbox_sts[MBOX_REG_COUNT]; 1022afaf5a2dSDavid Somayajulu int status = QLA_SUCCESS; 1023afaf5a2dSDavid Somayajulu 1024afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld:%d:%d: lun reset issued\n", ha->host_no, 1025f4f5df23SVikas Chaudhary ddb_entry->fw_ddb_index, lun)); 1026afaf5a2dSDavid Somayajulu 1027afaf5a2dSDavid Somayajulu /* 1028afaf5a2dSDavid Somayajulu * Send lun reset command to ISP, so that the ISP will return all 1029afaf5a2dSDavid Somayajulu * outstanding requests with RESET status 1030afaf5a2dSDavid Somayajulu */ 1031afaf5a2dSDavid Somayajulu memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 1032afaf5a2dSDavid Somayajulu memset(&mbox_sts, 0, sizeof(mbox_sts)); 1033c0e344c9SDavid C Somayajulu 1034afaf5a2dSDavid Somayajulu mbox_cmd[0] = MBOX_CMD_LUN_RESET; 1035afaf5a2dSDavid Somayajulu mbox_cmd[1] = ddb_entry->fw_ddb_index; 1036afaf5a2dSDavid Somayajulu mbox_cmd[2] = lun << 8; 1037afaf5a2dSDavid Somayajulu mbox_cmd[5] = 0x01; /* Immediate Command Enable */ 1038c0e344c9SDavid C Somayajulu 1039c0e344c9SDavid C Somayajulu qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]); 1040afaf5a2dSDavid Somayajulu if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE && 1041afaf5a2dSDavid Somayajulu mbox_sts[0] != MBOX_STS_COMMAND_ERROR) 1042afaf5a2dSDavid Somayajulu status = QLA_ERROR; 1043afaf5a2dSDavid Somayajulu 1044afaf5a2dSDavid Somayajulu return status; 1045afaf5a2dSDavid Somayajulu } 1046afaf5a2dSDavid Somayajulu 1047ce545039SMike Christie /** 1048ce545039SMike Christie * qla4xxx_reset_target - issues target Reset 1049ce545039SMike Christie * @ha: Pointer to host adapter structure. 1050ce545039SMike Christie * @db_entry: Pointer to device database entry 1051ce545039SMike Christie * @un_entry: Pointer to lun entry structure 1052ce545039SMike Christie * 1053ce545039SMike Christie * This routine performs a TARGET RESET on the specified target. 1054ce545039SMike Christie * The caller must ensure that the ddb_entry pointers 1055ce545039SMike Christie * are valid before calling this routine. 1056ce545039SMike Christie **/ 1057ce545039SMike Christie int qla4xxx_reset_target(struct scsi_qla_host *ha, 1058ce545039SMike Christie struct ddb_entry *ddb_entry) 1059ce545039SMike Christie { 1060ce545039SMike Christie uint32_t mbox_cmd[MBOX_REG_COUNT]; 1061ce545039SMike Christie uint32_t mbox_sts[MBOX_REG_COUNT]; 1062ce545039SMike Christie int status = QLA_SUCCESS; 1063ce545039SMike Christie 1064ce545039SMike Christie DEBUG2(printk("scsi%ld:%d: target reset issued\n", ha->host_no, 1065f4f5df23SVikas Chaudhary ddb_entry->fw_ddb_index)); 1066ce545039SMike Christie 1067ce545039SMike Christie /* 1068ce545039SMike Christie * Send target reset command to ISP, so that the ISP will return all 1069ce545039SMike Christie * outstanding requests with RESET status 1070ce545039SMike Christie */ 1071ce545039SMike Christie memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 1072ce545039SMike Christie memset(&mbox_sts, 0, sizeof(mbox_sts)); 1073ce545039SMike Christie 1074ce545039SMike Christie mbox_cmd[0] = MBOX_CMD_TARGET_WARM_RESET; 1075ce545039SMike Christie mbox_cmd[1] = ddb_entry->fw_ddb_index; 1076ce545039SMike Christie mbox_cmd[5] = 0x01; /* Immediate Command Enable */ 1077ce545039SMike Christie 1078ce545039SMike Christie qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], 1079ce545039SMike Christie &mbox_sts[0]); 1080ce545039SMike Christie if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE && 1081ce545039SMike Christie mbox_sts[0] != MBOX_STS_COMMAND_ERROR) 1082ce545039SMike Christie status = QLA_ERROR; 1083ce545039SMike Christie 1084ce545039SMike Christie return status; 1085ce545039SMike Christie } 1086afaf5a2dSDavid Somayajulu 1087afaf5a2dSDavid Somayajulu int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr, 1088afaf5a2dSDavid Somayajulu uint32_t offset, uint32_t len) 1089afaf5a2dSDavid Somayajulu { 1090afaf5a2dSDavid Somayajulu uint32_t mbox_cmd[MBOX_REG_COUNT]; 1091afaf5a2dSDavid Somayajulu uint32_t mbox_sts[MBOX_REG_COUNT]; 1092afaf5a2dSDavid Somayajulu 1093afaf5a2dSDavid Somayajulu memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 1094afaf5a2dSDavid Somayajulu memset(&mbox_sts, 0, sizeof(mbox_sts)); 1095c0e344c9SDavid C Somayajulu 1096afaf5a2dSDavid Somayajulu mbox_cmd[0] = MBOX_CMD_READ_FLASH; 1097afaf5a2dSDavid Somayajulu mbox_cmd[1] = LSDW(dma_addr); 1098afaf5a2dSDavid Somayajulu mbox_cmd[2] = MSDW(dma_addr); 1099afaf5a2dSDavid Somayajulu mbox_cmd[3] = offset; 1100afaf5a2dSDavid Somayajulu mbox_cmd[4] = len; 1101c0e344c9SDavid C Somayajulu 1102c0e344c9SDavid C Somayajulu if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 2, &mbox_cmd[0], &mbox_sts[0]) != 1103afaf5a2dSDavid Somayajulu QLA_SUCCESS) { 1104afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld: %s: MBOX_CMD_READ_FLASH, failed w/ " 1105afaf5a2dSDavid Somayajulu "status %04X %04X, offset %08x, len %08x\n", ha->host_no, 1106afaf5a2dSDavid Somayajulu __func__, mbox_sts[0], mbox_sts[1], offset, len)); 1107afaf5a2dSDavid Somayajulu return QLA_ERROR; 1108afaf5a2dSDavid Somayajulu } 1109afaf5a2dSDavid Somayajulu return QLA_SUCCESS; 1110afaf5a2dSDavid Somayajulu } 1111afaf5a2dSDavid Somayajulu 1112afaf5a2dSDavid Somayajulu /** 11137ad633c0SHarish Zunjarrao * qla4xxx_about_firmware - gets FW, iscsi draft and boot loader version 1114afaf5a2dSDavid Somayajulu * @ha: Pointer to host adapter structure. 1115afaf5a2dSDavid Somayajulu * 11167ad633c0SHarish Zunjarrao * Retrieves the FW version, iSCSI draft version & bootloader version of HBA. 11177ad633c0SHarish Zunjarrao * Mailboxes 2 & 3 may hold an address for data. Make sure that we write 0 to 11187ad633c0SHarish Zunjarrao * those mailboxes, if unused. 1119afaf5a2dSDavid Somayajulu **/ 11207ad633c0SHarish Zunjarrao int qla4xxx_about_firmware(struct scsi_qla_host *ha) 1121afaf5a2dSDavid Somayajulu { 11227ad633c0SHarish Zunjarrao struct about_fw_info *about_fw = NULL; 11237ad633c0SHarish Zunjarrao dma_addr_t about_fw_dma; 1124afaf5a2dSDavid Somayajulu uint32_t mbox_cmd[MBOX_REG_COUNT]; 1125afaf5a2dSDavid Somayajulu uint32_t mbox_sts[MBOX_REG_COUNT]; 11267ad633c0SHarish Zunjarrao int status = QLA_ERROR; 1127afaf5a2dSDavid Somayajulu 11287ad633c0SHarish Zunjarrao about_fw = dma_alloc_coherent(&ha->pdev->dev, 11297ad633c0SHarish Zunjarrao sizeof(struct about_fw_info), 11307ad633c0SHarish Zunjarrao &about_fw_dma, GFP_KERNEL); 11317ad633c0SHarish Zunjarrao if (!about_fw) { 11327ad633c0SHarish Zunjarrao DEBUG2(ql4_printk(KERN_ERR, ha, "%s: Unable to alloc memory " 11337ad633c0SHarish Zunjarrao "for about_fw\n", __func__)); 11347ad633c0SHarish Zunjarrao return status; 11357ad633c0SHarish Zunjarrao } 11367ad633c0SHarish Zunjarrao 11377ad633c0SHarish Zunjarrao memset(about_fw, 0, sizeof(struct about_fw_info)); 1138afaf5a2dSDavid Somayajulu memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 1139afaf5a2dSDavid Somayajulu memset(&mbox_sts, 0, sizeof(mbox_sts)); 1140c0e344c9SDavid C Somayajulu 1141afaf5a2dSDavid Somayajulu mbox_cmd[0] = MBOX_CMD_ABOUT_FW; 11427ad633c0SHarish Zunjarrao mbox_cmd[2] = LSDW(about_fw_dma); 11437ad633c0SHarish Zunjarrao mbox_cmd[3] = MSDW(about_fw_dma); 11447ad633c0SHarish Zunjarrao mbox_cmd[4] = sizeof(struct about_fw_info); 1145c0e344c9SDavid C Somayajulu 11467ad633c0SHarish Zunjarrao status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, MBOX_REG_COUNT, 11477ad633c0SHarish Zunjarrao &mbox_cmd[0], &mbox_sts[0]); 11487ad633c0SHarish Zunjarrao if (status != QLA_SUCCESS) { 11497ad633c0SHarish Zunjarrao DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: MBOX_CMD_ABOUT_FW " 11507ad633c0SHarish Zunjarrao "failed w/ status %04X\n", __func__, 11517ad633c0SHarish Zunjarrao mbox_sts[0])); 11527ad633c0SHarish Zunjarrao goto exit_about_fw; 1153afaf5a2dSDavid Somayajulu } 1154afaf5a2dSDavid Somayajulu 11557ad633c0SHarish Zunjarrao /* Save version information. */ 11567ad633c0SHarish Zunjarrao ha->firmware_version[0] = le16_to_cpu(about_fw->fw_major); 11577ad633c0SHarish Zunjarrao ha->firmware_version[1] = le16_to_cpu(about_fw->fw_minor); 11587ad633c0SHarish Zunjarrao ha->patch_number = le16_to_cpu(about_fw->fw_patch); 11597ad633c0SHarish Zunjarrao ha->build_number = le16_to_cpu(about_fw->fw_build); 11607ad633c0SHarish Zunjarrao ha->iscsi_major = le16_to_cpu(about_fw->iscsi_major); 11617ad633c0SHarish Zunjarrao ha->iscsi_minor = le16_to_cpu(about_fw->iscsi_minor); 11627ad633c0SHarish Zunjarrao ha->bootload_major = le16_to_cpu(about_fw->bootload_major); 11637ad633c0SHarish Zunjarrao ha->bootload_minor = le16_to_cpu(about_fw->bootload_minor); 11647ad633c0SHarish Zunjarrao ha->bootload_patch = le16_to_cpu(about_fw->bootload_patch); 11657ad633c0SHarish Zunjarrao ha->bootload_build = le16_to_cpu(about_fw->bootload_build); 11667ad633c0SHarish Zunjarrao status = QLA_SUCCESS; 1167afaf5a2dSDavid Somayajulu 11687ad633c0SHarish Zunjarrao exit_about_fw: 11697ad633c0SHarish Zunjarrao dma_free_coherent(&ha->pdev->dev, sizeof(struct about_fw_info), 11707ad633c0SHarish Zunjarrao about_fw, about_fw_dma); 11717ad633c0SHarish Zunjarrao return status; 1172afaf5a2dSDavid Somayajulu } 1173afaf5a2dSDavid Somayajulu 1174b3a271a9SManish Rangankar static int qla4xxx_get_default_ddb(struct scsi_qla_host *ha, uint32_t options, 117547975477SAdrian Bunk dma_addr_t dma_addr) 1176afaf5a2dSDavid Somayajulu { 1177afaf5a2dSDavid Somayajulu uint32_t mbox_cmd[MBOX_REG_COUNT]; 1178afaf5a2dSDavid Somayajulu uint32_t mbox_sts[MBOX_REG_COUNT]; 1179afaf5a2dSDavid Somayajulu 1180afaf5a2dSDavid Somayajulu memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 1181afaf5a2dSDavid Somayajulu memset(&mbox_sts, 0, sizeof(mbox_sts)); 1182afaf5a2dSDavid Somayajulu 1183afaf5a2dSDavid Somayajulu mbox_cmd[0] = MBOX_CMD_GET_DATABASE_ENTRY_DEFAULTS; 1184b3a271a9SManish Rangankar mbox_cmd[1] = options; 1185afaf5a2dSDavid Somayajulu mbox_cmd[2] = LSDW(dma_addr); 1186afaf5a2dSDavid Somayajulu mbox_cmd[3] = MSDW(dma_addr); 1187afaf5a2dSDavid Somayajulu 1188c0e344c9SDavid C Somayajulu if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]) != 1189afaf5a2dSDavid Somayajulu QLA_SUCCESS) { 1190afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld: %s: failed status %04X\n", 1191afaf5a2dSDavid Somayajulu ha->host_no, __func__, mbox_sts[0])); 1192afaf5a2dSDavid Somayajulu return QLA_ERROR; 1193afaf5a2dSDavid Somayajulu } 1194afaf5a2dSDavid Somayajulu return QLA_SUCCESS; 1195afaf5a2dSDavid Somayajulu } 1196afaf5a2dSDavid Somayajulu 1197b3a271a9SManish Rangankar int qla4xxx_req_ddb_entry(struct scsi_qla_host *ha, uint32_t ddb_index, 1198b3a271a9SManish Rangankar uint32_t *mbx_sts) 1199afaf5a2dSDavid Somayajulu { 1200b3a271a9SManish Rangankar int status; 1201afaf5a2dSDavid Somayajulu uint32_t mbox_cmd[MBOX_REG_COUNT]; 1202afaf5a2dSDavid Somayajulu uint32_t mbox_sts[MBOX_REG_COUNT]; 1203afaf5a2dSDavid Somayajulu 1204afaf5a2dSDavid Somayajulu memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 1205afaf5a2dSDavid Somayajulu memset(&mbox_sts, 0, sizeof(mbox_sts)); 1206afaf5a2dSDavid Somayajulu 1207afaf5a2dSDavid Somayajulu mbox_cmd[0] = MBOX_CMD_REQUEST_DATABASE_ENTRY; 1208b3a271a9SManish Rangankar mbox_cmd[1] = ddb_index; 1209afaf5a2dSDavid Somayajulu 1210b3a271a9SManish Rangankar status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], 1211b3a271a9SManish Rangankar &mbox_sts[0]); 1212b3a271a9SManish Rangankar if (status != QLA_SUCCESS) { 1213b3a271a9SManish Rangankar DEBUG2(ql4_printk(KERN_ERR, ha, "%s: failed status %04X\n", 1214b3a271a9SManish Rangankar __func__, mbox_sts[0])); 1215afaf5a2dSDavid Somayajulu } 1216afaf5a2dSDavid Somayajulu 1217b3a271a9SManish Rangankar *mbx_sts = mbox_sts[0]; 1218b3a271a9SManish Rangankar return status; 1219afaf5a2dSDavid Somayajulu } 1220afaf5a2dSDavid Somayajulu 1221b3a271a9SManish Rangankar int qla4xxx_clear_ddb_entry(struct scsi_qla_host *ha, uint32_t ddb_index) 1222b3a271a9SManish Rangankar { 1223b3a271a9SManish Rangankar int status; 1224b3a271a9SManish Rangankar uint32_t mbox_cmd[MBOX_REG_COUNT]; 1225b3a271a9SManish Rangankar uint32_t mbox_sts[MBOX_REG_COUNT]; 1226b3a271a9SManish Rangankar 1227b3a271a9SManish Rangankar memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 1228b3a271a9SManish Rangankar memset(&mbox_sts, 0, sizeof(mbox_sts)); 1229b3a271a9SManish Rangankar 1230b3a271a9SManish Rangankar mbox_cmd[0] = MBOX_CMD_CLEAR_DATABASE_ENTRY; 1231b3a271a9SManish Rangankar mbox_cmd[1] = ddb_index; 1232b3a271a9SManish Rangankar 1233b3a271a9SManish Rangankar status = qla4xxx_mailbox_command(ha, 2, 1, &mbox_cmd[0], 1234b3a271a9SManish Rangankar &mbox_sts[0]); 1235b3a271a9SManish Rangankar if (status != QLA_SUCCESS) { 1236b3a271a9SManish Rangankar DEBUG2(ql4_printk(KERN_ERR, ha, "%s: failed status %04X\n", 1237b3a271a9SManish Rangankar __func__, mbox_sts[0])); 1238b3a271a9SManish Rangankar } 1239b3a271a9SManish Rangankar 1240b3a271a9SManish Rangankar return status; 1241b3a271a9SManish Rangankar } 1242b3a271a9SManish Rangankar 1243d00efe3fSMike Christie int qla4xxx_set_flash(struct scsi_qla_host *ha, dma_addr_t dma_addr, 1244d00efe3fSMike Christie uint32_t offset, uint32_t length, uint32_t options) 1245d00efe3fSMike Christie { 1246d00efe3fSMike Christie uint32_t mbox_cmd[MBOX_REG_COUNT]; 1247d00efe3fSMike Christie uint32_t mbox_sts[MBOX_REG_COUNT]; 1248d00efe3fSMike Christie int status = QLA_SUCCESS; 1249d00efe3fSMike Christie 1250d00efe3fSMike Christie memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 1251d00efe3fSMike Christie memset(&mbox_sts, 0, sizeof(mbox_sts)); 1252d00efe3fSMike Christie 1253d00efe3fSMike Christie mbox_cmd[0] = MBOX_CMD_WRITE_FLASH; 1254d00efe3fSMike Christie mbox_cmd[1] = LSDW(dma_addr); 1255d00efe3fSMike Christie mbox_cmd[2] = MSDW(dma_addr); 1256d00efe3fSMike Christie mbox_cmd[3] = offset; 1257d00efe3fSMike Christie mbox_cmd[4] = length; 1258d00efe3fSMike Christie mbox_cmd[5] = options; 1259d00efe3fSMike Christie 1260d00efe3fSMike Christie status = qla4xxx_mailbox_command(ha, 6, 2, &mbox_cmd[0], &mbox_sts[0]); 1261d00efe3fSMike Christie if (status != QLA_SUCCESS) { 1262d00efe3fSMike Christie DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: MBOX_CMD_WRITE_FLASH " 1263d00efe3fSMike Christie "failed w/ status %04X, mbx1 %04X\n", 1264d00efe3fSMike Christie __func__, mbox_sts[0], mbox_sts[1])); 1265d00efe3fSMike Christie } 1266d00efe3fSMike Christie return status; 1267d00efe3fSMike Christie } 1268d00efe3fSMike Christie 12692a991c21SManish Rangankar int qla4xxx_bootdb_by_index(struct scsi_qla_host *ha, 12702a991c21SManish Rangankar struct dev_db_entry *fw_ddb_entry, 12712a991c21SManish Rangankar dma_addr_t fw_ddb_entry_dma, uint16_t ddb_index) 12722a991c21SManish Rangankar { 12732a991c21SManish Rangankar uint32_t dev_db_start_offset = FLASH_OFFSET_DB_INFO; 12742a991c21SManish Rangankar uint32_t dev_db_end_offset; 12752a991c21SManish Rangankar int status = QLA_ERROR; 12762a991c21SManish Rangankar 12772a991c21SManish Rangankar memset(fw_ddb_entry, 0, sizeof(*fw_ddb_entry)); 12782a991c21SManish Rangankar 12792a991c21SManish Rangankar dev_db_start_offset += (ddb_index * sizeof(*fw_ddb_entry)); 12802a991c21SManish Rangankar dev_db_end_offset = FLASH_OFFSET_DB_END; 12812a991c21SManish Rangankar 12822a991c21SManish Rangankar if (dev_db_start_offset > dev_db_end_offset) { 12832a991c21SManish Rangankar DEBUG2(ql4_printk(KERN_ERR, ha, 12842a991c21SManish Rangankar "%s:Invalid DDB index %d", __func__, 12852a991c21SManish Rangankar ddb_index)); 12862a991c21SManish Rangankar goto exit_bootdb_failed; 12872a991c21SManish Rangankar } 12882a991c21SManish Rangankar 12892a991c21SManish Rangankar if (qla4xxx_get_flash(ha, fw_ddb_entry_dma, dev_db_start_offset, 12902a991c21SManish Rangankar sizeof(*fw_ddb_entry)) != QLA_SUCCESS) { 12912a991c21SManish Rangankar ql4_printk(KERN_ERR, ha, "scsi%ld: %s: Get Flash" 12922a991c21SManish Rangankar "failed\n", ha->host_no, __func__); 12932a991c21SManish Rangankar goto exit_bootdb_failed; 12942a991c21SManish Rangankar } 12952a991c21SManish Rangankar 12962a991c21SManish Rangankar if (fw_ddb_entry->cookie == DDB_VALID_COOKIE) 12972a991c21SManish Rangankar status = QLA_SUCCESS; 12982a991c21SManish Rangankar 12992a991c21SManish Rangankar exit_bootdb_failed: 13002a991c21SManish Rangankar return status; 13012a991c21SManish Rangankar } 13022a991c21SManish Rangankar 13032a991c21SManish Rangankar int qla4xxx_get_chap(struct scsi_qla_host *ha, char *username, char *password, 13042a991c21SManish Rangankar uint16_t idx) 13052a991c21SManish Rangankar { 13062a991c21SManish Rangankar int ret = 0; 13072a991c21SManish Rangankar int rval = QLA_ERROR; 13082a991c21SManish Rangankar uint32_t offset = 0; 13092a991c21SManish Rangankar struct ql4_chap_table *chap_table; 13102a991c21SManish Rangankar dma_addr_t chap_dma; 13112a991c21SManish Rangankar 13122a991c21SManish Rangankar chap_table = dma_pool_alloc(ha->chap_dma_pool, GFP_KERNEL, &chap_dma); 13132a991c21SManish Rangankar if (chap_table == NULL) { 13142a991c21SManish Rangankar ret = -ENOMEM; 13152a991c21SManish Rangankar goto exit_get_chap; 13162a991c21SManish Rangankar } 13172a991c21SManish Rangankar 13182a991c21SManish Rangankar memset(chap_table, 0, sizeof(struct ql4_chap_table)); 13192a991c21SManish Rangankar 13202a991c21SManish Rangankar offset = 0x06000000 | (idx * sizeof(struct ql4_chap_table)); 13212a991c21SManish Rangankar 13222a991c21SManish Rangankar rval = qla4xxx_get_flash(ha, chap_dma, offset, 13232a991c21SManish Rangankar sizeof(struct ql4_chap_table)); 13242a991c21SManish Rangankar if (rval != QLA_SUCCESS) { 13252a991c21SManish Rangankar ret = -EINVAL; 13262a991c21SManish Rangankar goto exit_get_chap; 13272a991c21SManish Rangankar } 13282a991c21SManish Rangankar 13292a991c21SManish Rangankar DEBUG2(ql4_printk(KERN_INFO, ha, "Chap Cookie: x%x\n", 13302a991c21SManish Rangankar __le16_to_cpu(chap_table->cookie))); 13312a991c21SManish Rangankar 13322a991c21SManish Rangankar if (__le16_to_cpu(chap_table->cookie) != CHAP_VALID_COOKIE) { 13332a991c21SManish Rangankar ql4_printk(KERN_ERR, ha, "No valid chap entry found\n"); 13342a991c21SManish Rangankar goto exit_get_chap; 13352a991c21SManish Rangankar } 13362a991c21SManish Rangankar 13372a991c21SManish Rangankar strncpy(password, chap_table->secret, QL4_CHAP_MAX_SECRET_LEN); 13382a991c21SManish Rangankar strncpy(username, chap_table->name, QL4_CHAP_MAX_NAME_LEN); 13392a991c21SManish Rangankar chap_table->cookie = __constant_cpu_to_le16(CHAP_VALID_COOKIE); 13402a991c21SManish Rangankar 13412a991c21SManish Rangankar exit_get_chap: 13422a991c21SManish Rangankar dma_pool_free(ha->chap_dma_pool, chap_table, chap_dma); 13432a991c21SManish Rangankar return ret; 13442a991c21SManish Rangankar } 13452a991c21SManish Rangankar 1346b3a271a9SManish Rangankar static int qla4xxx_set_chap(struct scsi_qla_host *ha, char *username, 1347b3a271a9SManish Rangankar char *password, uint16_t idx, int bidi) 1348b3a271a9SManish Rangankar { 1349b3a271a9SManish Rangankar int ret = 0; 1350b3a271a9SManish Rangankar int rval = QLA_ERROR; 1351b3a271a9SManish Rangankar uint32_t offset = 0; 1352b3a271a9SManish Rangankar struct ql4_chap_table *chap_table; 1353b3a271a9SManish Rangankar dma_addr_t chap_dma; 1354b3a271a9SManish Rangankar 1355b3a271a9SManish Rangankar chap_table = dma_pool_alloc(ha->chap_dma_pool, GFP_KERNEL, &chap_dma); 1356b3a271a9SManish Rangankar if (chap_table == NULL) { 1357b3a271a9SManish Rangankar ret = -ENOMEM; 1358b3a271a9SManish Rangankar goto exit_set_chap; 1359b3a271a9SManish Rangankar } 1360b3a271a9SManish Rangankar 1361b3a271a9SManish Rangankar memset(chap_table, 0, sizeof(struct ql4_chap_table)); 1362b3a271a9SManish Rangankar if (bidi) 1363b3a271a9SManish Rangankar chap_table->flags |= BIT_6; /* peer */ 1364b3a271a9SManish Rangankar else 1365b3a271a9SManish Rangankar chap_table->flags |= BIT_7; /* local */ 1366b3a271a9SManish Rangankar chap_table->secret_len = strlen(password); 1367b3a271a9SManish Rangankar strncpy(chap_table->secret, password, MAX_CHAP_SECRET_LEN); 1368b3a271a9SManish Rangankar strncpy(chap_table->name, username, MAX_CHAP_NAME_LEN); 1369b3a271a9SManish Rangankar chap_table->cookie = __constant_cpu_to_le16(CHAP_VALID_COOKIE); 1370b3a271a9SManish Rangankar offset = 0x06000000 | (idx * sizeof(struct ql4_chap_table)); 1371b3a271a9SManish Rangankar rval = qla4xxx_set_flash(ha, chap_dma, offset, 1372b3a271a9SManish Rangankar sizeof(struct ql4_chap_table), 1373b3a271a9SManish Rangankar FLASH_OPT_RMW_COMMIT); 1374b3a271a9SManish Rangankar dma_pool_free(ha->chap_dma_pool, chap_table, chap_dma); 1375b3a271a9SManish Rangankar if (rval != QLA_SUCCESS) 1376b3a271a9SManish Rangankar ret = -EINVAL; 1377b3a271a9SManish Rangankar 1378b3a271a9SManish Rangankar exit_set_chap: 1379b3a271a9SManish Rangankar return ret; 1380b3a271a9SManish Rangankar } 1381b3a271a9SManish Rangankar 1382d00efe3fSMike Christie int qla4xxx_conn_close_sess_logout(struct scsi_qla_host *ha, 1383d00efe3fSMike Christie uint16_t fw_ddb_index, 1384d00efe3fSMike Christie uint16_t connection_id, 1385d00efe3fSMike Christie uint16_t option) 1386d00efe3fSMike Christie { 1387d00efe3fSMike Christie uint32_t mbox_cmd[MBOX_REG_COUNT]; 1388d00efe3fSMike Christie uint32_t mbox_sts[MBOX_REG_COUNT]; 1389d00efe3fSMike Christie int status = QLA_SUCCESS; 1390d00efe3fSMike Christie 1391d00efe3fSMike Christie memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 1392d00efe3fSMike Christie memset(&mbox_sts, 0, sizeof(mbox_sts)); 1393d00efe3fSMike Christie 1394d00efe3fSMike Christie mbox_cmd[0] = MBOX_CMD_CONN_CLOSE_SESS_LOGOUT; 1395d00efe3fSMike Christie mbox_cmd[1] = fw_ddb_index; 1396d00efe3fSMike Christie mbox_cmd[2] = connection_id; 1397d00efe3fSMike Christie mbox_cmd[3] = option; 1398d00efe3fSMike Christie 1399d00efe3fSMike Christie status = qla4xxx_mailbox_command(ha, 4, 2, &mbox_cmd[0], &mbox_sts[0]); 1400d00efe3fSMike Christie if (status != QLA_SUCCESS) { 1401d00efe3fSMike Christie DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: MBOX_CMD_CONN_CLOSE " 1402d00efe3fSMike Christie "option %04x failed w/ status %04X %04X\n", 1403d00efe3fSMike Christie __func__, option, mbox_sts[0], mbox_sts[1])); 1404d00efe3fSMike Christie } 1405d00efe3fSMike Christie return status; 1406d00efe3fSMike Christie } 1407d00efe3fSMike Christie 1408d00efe3fSMike Christie int qla4xxx_disable_acb(struct scsi_qla_host *ha) 1409d00efe3fSMike Christie { 1410d00efe3fSMike Christie uint32_t mbox_cmd[MBOX_REG_COUNT]; 1411d00efe3fSMike Christie uint32_t mbox_sts[MBOX_REG_COUNT]; 1412d00efe3fSMike Christie int status = QLA_SUCCESS; 1413d00efe3fSMike Christie 1414d00efe3fSMike Christie memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 1415d00efe3fSMike Christie memset(&mbox_sts, 0, sizeof(mbox_sts)); 1416d00efe3fSMike Christie 1417d00efe3fSMike Christie mbox_cmd[0] = MBOX_CMD_DISABLE_ACB; 1418d00efe3fSMike Christie 1419d00efe3fSMike Christie status = qla4xxx_mailbox_command(ha, 8, 5, &mbox_cmd[0], &mbox_sts[0]); 1420d00efe3fSMike Christie if (status != QLA_SUCCESS) { 1421d00efe3fSMike Christie DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: MBOX_CMD_DISABLE_ACB " 1422d00efe3fSMike Christie "failed w/ status %04X %04X %04X", __func__, 1423d00efe3fSMike Christie mbox_sts[0], mbox_sts[1], mbox_sts[2])); 1424d00efe3fSMike Christie } 1425d00efe3fSMike Christie return status; 1426d00efe3fSMike Christie } 1427d00efe3fSMike Christie 1428*6085491cSHarish Zunjarrao int qla4xxx_get_acb(struct scsi_qla_host *ha, dma_addr_t acb_dma, 1429*6085491cSHarish Zunjarrao uint32_t acb_type, uint32_t len) 1430d00efe3fSMike Christie { 1431*6085491cSHarish Zunjarrao uint32_t mbox_cmd[MBOX_REG_COUNT]; 1432*6085491cSHarish Zunjarrao uint32_t mbox_sts[MBOX_REG_COUNT]; 1433d00efe3fSMike Christie int status = QLA_SUCCESS; 1434d00efe3fSMike Christie 1435*6085491cSHarish Zunjarrao memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 1436*6085491cSHarish Zunjarrao memset(&mbox_sts, 0, sizeof(mbox_sts)); 1437*6085491cSHarish Zunjarrao 1438d00efe3fSMike Christie mbox_cmd[0] = MBOX_CMD_GET_ACB; 1439*6085491cSHarish Zunjarrao mbox_cmd[1] = acb_type; 1440d00efe3fSMike Christie mbox_cmd[2] = LSDW(acb_dma); 1441d00efe3fSMike Christie mbox_cmd[3] = MSDW(acb_dma); 1442*6085491cSHarish Zunjarrao mbox_cmd[4] = len; 1443d00efe3fSMike Christie 1444d00efe3fSMike Christie status = qla4xxx_mailbox_command(ha, 5, 5, &mbox_cmd[0], &mbox_sts[0]); 1445d00efe3fSMike Christie if (status != QLA_SUCCESS) { 1446d00efe3fSMike Christie DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: MBOX_CMD_GET_ACB " 1447d00efe3fSMike Christie "failed w/ status %04X\n", __func__, 1448d00efe3fSMike Christie mbox_sts[0])); 1449d00efe3fSMike Christie } 1450d00efe3fSMike Christie return status; 1451d00efe3fSMike Christie } 1452d00efe3fSMike Christie 1453d00efe3fSMike Christie int qla4xxx_set_acb(struct scsi_qla_host *ha, uint32_t *mbox_cmd, 1454d00efe3fSMike Christie uint32_t *mbox_sts, dma_addr_t acb_dma) 1455d00efe3fSMike Christie { 1456d00efe3fSMike Christie int status = QLA_SUCCESS; 1457d00efe3fSMike Christie 1458d00efe3fSMike Christie memset(mbox_cmd, 0, sizeof(mbox_cmd[0]) * MBOX_REG_COUNT); 1459d00efe3fSMike Christie memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT); 1460d00efe3fSMike Christie mbox_cmd[0] = MBOX_CMD_SET_ACB; 1461d00efe3fSMike Christie mbox_cmd[1] = 0; /* Primary ACB */ 1462d00efe3fSMike Christie mbox_cmd[2] = LSDW(acb_dma); 1463d00efe3fSMike Christie mbox_cmd[3] = MSDW(acb_dma); 1464d00efe3fSMike Christie mbox_cmd[4] = sizeof(struct addr_ctrl_blk); 1465d00efe3fSMike Christie 1466d00efe3fSMike Christie status = qla4xxx_mailbox_command(ha, 5, 5, &mbox_cmd[0], &mbox_sts[0]); 1467d00efe3fSMike Christie if (status != QLA_SUCCESS) { 1468d00efe3fSMike Christie DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: MBOX_CMD_SET_ACB " 1469d00efe3fSMike Christie "failed w/ status %04X\n", __func__, 1470d00efe3fSMike Christie mbox_sts[0])); 1471d00efe3fSMike Christie } 1472d00efe3fSMike Christie return status; 1473d00efe3fSMike Christie } 1474b3a271a9SManish Rangankar 1475b3a271a9SManish Rangankar int qla4xxx_set_param_ddbentry(struct scsi_qla_host *ha, 1476b3a271a9SManish Rangankar struct ddb_entry *ddb_entry, 1477b3a271a9SManish Rangankar struct iscsi_cls_conn *cls_conn, 1478b3a271a9SManish Rangankar uint32_t *mbx_sts) 1479b3a271a9SManish Rangankar { 1480b3a271a9SManish Rangankar struct dev_db_entry *fw_ddb_entry; 1481b3a271a9SManish Rangankar struct iscsi_conn *conn; 1482b3a271a9SManish Rangankar struct iscsi_session *sess; 1483b3a271a9SManish Rangankar struct qla_conn *qla_conn; 1484b3a271a9SManish Rangankar struct sockaddr *dst_addr; 1485b3a271a9SManish Rangankar dma_addr_t fw_ddb_entry_dma; 1486b3a271a9SManish Rangankar int status = QLA_SUCCESS; 1487b3a271a9SManish Rangankar int rval = 0; 1488b3a271a9SManish Rangankar struct sockaddr_in *addr; 1489b3a271a9SManish Rangankar struct sockaddr_in6 *addr6; 1490b3a271a9SManish Rangankar char *ip; 1491b3a271a9SManish Rangankar uint16_t iscsi_opts = 0; 1492b3a271a9SManish Rangankar uint32_t options = 0; 1493b3a271a9SManish Rangankar uint16_t idx; 1494b3a271a9SManish Rangankar int max_chap_entries = 0; 1495b3a271a9SManish Rangankar 1496b3a271a9SManish Rangankar fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), 1497b3a271a9SManish Rangankar &fw_ddb_entry_dma, GFP_KERNEL); 1498b3a271a9SManish Rangankar if (!fw_ddb_entry) { 1499b3a271a9SManish Rangankar DEBUG2(ql4_printk(KERN_ERR, ha, 1500b3a271a9SManish Rangankar "%s: Unable to allocate dma buffer.\n", 1501b3a271a9SManish Rangankar __func__)); 1502b3a271a9SManish Rangankar rval = -ENOMEM; 1503b3a271a9SManish Rangankar goto exit_set_param_no_free; 1504b3a271a9SManish Rangankar } 1505b3a271a9SManish Rangankar 1506b3a271a9SManish Rangankar conn = cls_conn->dd_data; 1507b3a271a9SManish Rangankar qla_conn = conn->dd_data; 1508b3a271a9SManish Rangankar sess = conn->session; 1509b3a271a9SManish Rangankar dst_addr = &qla_conn->qla_ep->dst_addr; 1510b3a271a9SManish Rangankar 1511b3a271a9SManish Rangankar if (dst_addr->sa_family == AF_INET6) 1512b3a271a9SManish Rangankar options |= IPV6_DEFAULT_DDB_ENTRY; 1513b3a271a9SManish Rangankar 1514b3a271a9SManish Rangankar status = qla4xxx_get_default_ddb(ha, options, fw_ddb_entry_dma); 1515b3a271a9SManish Rangankar if (status == QLA_ERROR) { 1516b3a271a9SManish Rangankar rval = -EINVAL; 1517b3a271a9SManish Rangankar goto exit_set_param; 1518b3a271a9SManish Rangankar } 1519b3a271a9SManish Rangankar 1520b3a271a9SManish Rangankar iscsi_opts = le16_to_cpu(fw_ddb_entry->iscsi_options); 1521b3a271a9SManish Rangankar memset(fw_ddb_entry->iscsi_alias, 0, sizeof(fw_ddb_entry->iscsi_alias)); 1522b3a271a9SManish Rangankar 1523b3a271a9SManish Rangankar memset(fw_ddb_entry->iscsi_name, 0, sizeof(fw_ddb_entry->iscsi_name)); 1524b3a271a9SManish Rangankar 1525b3a271a9SManish Rangankar if (sess->targetname != NULL) { 1526b3a271a9SManish Rangankar memcpy(fw_ddb_entry->iscsi_name, sess->targetname, 1527b3a271a9SManish Rangankar min(strlen(sess->targetname), 1528b3a271a9SManish Rangankar sizeof(fw_ddb_entry->iscsi_name))); 1529b3a271a9SManish Rangankar } 1530b3a271a9SManish Rangankar 1531b3a271a9SManish Rangankar memset(fw_ddb_entry->ip_addr, 0, sizeof(fw_ddb_entry->ip_addr)); 1532b3a271a9SManish Rangankar memset(fw_ddb_entry->tgt_addr, 0, sizeof(fw_ddb_entry->tgt_addr)); 1533b3a271a9SManish Rangankar 1534b3a271a9SManish Rangankar fw_ddb_entry->options = DDB_OPT_TARGET | DDB_OPT_AUTO_SENDTGTS_DISABLE; 1535b3a271a9SManish Rangankar 1536b3a271a9SManish Rangankar if (dst_addr->sa_family == AF_INET) { 1537b3a271a9SManish Rangankar addr = (struct sockaddr_in *)dst_addr; 1538b3a271a9SManish Rangankar ip = (char *)&addr->sin_addr; 1539b3a271a9SManish Rangankar memcpy(fw_ddb_entry->ip_addr, ip, IP_ADDR_LEN); 1540b3a271a9SManish Rangankar fw_ddb_entry->port = cpu_to_le16(ntohs(addr->sin_port)); 1541b3a271a9SManish Rangankar DEBUG2(ql4_printk(KERN_INFO, ha, 1542b3a271a9SManish Rangankar "%s: Destination Address [%pI4]: index [%d]\n", 1543b3a271a9SManish Rangankar __func__, fw_ddb_entry->ip_addr, 1544b3a271a9SManish Rangankar ddb_entry->fw_ddb_index)); 1545b3a271a9SManish Rangankar } else if (dst_addr->sa_family == AF_INET6) { 1546b3a271a9SManish Rangankar addr6 = (struct sockaddr_in6 *)dst_addr; 1547b3a271a9SManish Rangankar ip = (char *)&addr6->sin6_addr; 1548b3a271a9SManish Rangankar memcpy(fw_ddb_entry->ip_addr, ip, IPv6_ADDR_LEN); 1549b3a271a9SManish Rangankar fw_ddb_entry->port = cpu_to_le16(ntohs(addr6->sin6_port)); 1550b3a271a9SManish Rangankar fw_ddb_entry->options |= DDB_OPT_IPV6_DEVICE; 1551b3a271a9SManish Rangankar DEBUG2(ql4_printk(KERN_INFO, ha, 1552b3a271a9SManish Rangankar "%s: Destination Address [%pI6]: index [%d]\n", 1553b3a271a9SManish Rangankar __func__, fw_ddb_entry->ip_addr, 1554b3a271a9SManish Rangankar ddb_entry->fw_ddb_index)); 1555b3a271a9SManish Rangankar } else { 1556b3a271a9SManish Rangankar ql4_printk(KERN_ERR, ha, 1557b3a271a9SManish Rangankar "%s: Failed to get IP Address\n", 1558b3a271a9SManish Rangankar __func__); 1559b3a271a9SManish Rangankar rval = -EINVAL; 1560b3a271a9SManish Rangankar goto exit_set_param; 1561b3a271a9SManish Rangankar } 1562b3a271a9SManish Rangankar 1563b3a271a9SManish Rangankar if (is_qla8022(ha)) 1564b3a271a9SManish Rangankar max_chap_entries = MAX_CHAP_ENTRIES_82XX; 1565b3a271a9SManish Rangankar else 1566b3a271a9SManish Rangankar max_chap_entries = MAX_CHAP_ENTRIES_40XX; 1567b3a271a9SManish Rangankar /* CHAP */ 1568b3a271a9SManish Rangankar if (sess->username != NULL && sess->password != NULL) { 1569b3a271a9SManish Rangankar if (strlen(sess->username) && strlen(sess->password)) { 1570b3a271a9SManish Rangankar iscsi_opts |= BIT_7; 1571b3a271a9SManish Rangankar idx = ddb_entry->fw_ddb_index * 2; 1572b3a271a9SManish Rangankar if (idx > max_chap_entries) { 1573b3a271a9SManish Rangankar ql4_printk(KERN_ERR, ha, 1574b3a271a9SManish Rangankar "%s: Invalid ddb or chap index\n", 1575b3a271a9SManish Rangankar __func__); 1576b3a271a9SManish Rangankar rval = -EINVAL; 1577b3a271a9SManish Rangankar goto exit_set_param; 1578b3a271a9SManish Rangankar } 1579b3a271a9SManish Rangankar 1580b3a271a9SManish Rangankar rval = qla4xxx_set_chap(ha, sess->username, 1581b3a271a9SManish Rangankar sess->password, idx, 0); 1582b3a271a9SManish Rangankar if (rval) 1583b3a271a9SManish Rangankar goto exit_set_param; 1584b3a271a9SManish Rangankar 1585b3a271a9SManish Rangankar fw_ddb_entry->chap_tbl_idx = cpu_to_le16(idx); 1586b3a271a9SManish Rangankar } 1587b3a271a9SManish Rangankar } 1588b3a271a9SManish Rangankar 1589b3a271a9SManish Rangankar if (sess->username_in != NULL && sess->password_in != NULL) { 1590b3a271a9SManish Rangankar /* Check if BIDI CHAP */ 1591b3a271a9SManish Rangankar if (strlen(sess->username_in) && strlen(sess->password_in)) { 1592b3a271a9SManish Rangankar iscsi_opts |= BIT_4; 1593b3a271a9SManish Rangankar idx = (ddb_entry->fw_ddb_index * 2) + 1; 1594b3a271a9SManish Rangankar if (idx > max_chap_entries) { 1595b3a271a9SManish Rangankar ql4_printk(KERN_ERR, ha, 1596b3a271a9SManish Rangankar "%s: Invalid ddb or bidi chap " 1597b3a271a9SManish Rangankar "index\n", __func__); 1598b3a271a9SManish Rangankar rval = -EINVAL; 1599b3a271a9SManish Rangankar goto exit_set_param; 1600b3a271a9SManish Rangankar } 1601b3a271a9SManish Rangankar rval = qla4xxx_set_chap(ha, sess->username_in, 1602b3a271a9SManish Rangankar sess->password_in, idx, 0); 1603b3a271a9SManish Rangankar if (rval) 1604b3a271a9SManish Rangankar goto exit_set_param; 1605b3a271a9SManish Rangankar } 1606b3a271a9SManish Rangankar } 1607b3a271a9SManish Rangankar 1608b3a271a9SManish Rangankar if (sess->initial_r2t_en) 1609b3a271a9SManish Rangankar iscsi_opts |= BIT_10; 1610b3a271a9SManish Rangankar 1611b3a271a9SManish Rangankar if (sess->imm_data_en) 1612b3a271a9SManish Rangankar iscsi_opts |= BIT_11; 1613b3a271a9SManish Rangankar 1614b3a271a9SManish Rangankar fw_ddb_entry->iscsi_options = cpu_to_le16(iscsi_opts); 1615b3a271a9SManish Rangankar 1616b3a271a9SManish Rangankar if (conn->max_recv_dlength) 1617b3a271a9SManish Rangankar fw_ddb_entry->iscsi_max_rcv_data_seg_len = 1618b3a271a9SManish Rangankar __constant_cpu_to_le16((conn->max_recv_dlength / BYTE_UNITS)); 1619b3a271a9SManish Rangankar 1620b3a271a9SManish Rangankar if (sess->max_r2t) 1621b3a271a9SManish Rangankar fw_ddb_entry->iscsi_max_outsnd_r2t = cpu_to_le16(sess->max_r2t); 1622b3a271a9SManish Rangankar 1623b3a271a9SManish Rangankar if (sess->first_burst) 1624b3a271a9SManish Rangankar fw_ddb_entry->iscsi_first_burst_len = 1625b3a271a9SManish Rangankar __constant_cpu_to_le16((sess->first_burst / BYTE_UNITS)); 1626b3a271a9SManish Rangankar 1627b3a271a9SManish Rangankar if (sess->max_burst) 1628b3a271a9SManish Rangankar fw_ddb_entry->iscsi_max_burst_len = 1629b3a271a9SManish Rangankar __constant_cpu_to_le16((sess->max_burst / BYTE_UNITS)); 1630b3a271a9SManish Rangankar 1631b3a271a9SManish Rangankar if (sess->time2wait) 1632b3a271a9SManish Rangankar fw_ddb_entry->iscsi_def_time2wait = 1633b3a271a9SManish Rangankar cpu_to_le16(sess->time2wait); 1634b3a271a9SManish Rangankar 1635b3a271a9SManish Rangankar if (sess->time2retain) 1636b3a271a9SManish Rangankar fw_ddb_entry->iscsi_def_time2retain = 1637b3a271a9SManish Rangankar cpu_to_le16(sess->time2retain); 1638b3a271a9SManish Rangankar 1639b3a271a9SManish Rangankar status = qla4xxx_set_ddb_entry(ha, ddb_entry->fw_ddb_index, 1640b3a271a9SManish Rangankar fw_ddb_entry_dma, mbx_sts); 1641b3a271a9SManish Rangankar 1642b3a271a9SManish Rangankar if (status != QLA_SUCCESS) 1643b3a271a9SManish Rangankar rval = -EINVAL; 1644b3a271a9SManish Rangankar exit_set_param: 1645b3a271a9SManish Rangankar dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), 1646b3a271a9SManish Rangankar fw_ddb_entry, fw_ddb_entry_dma); 1647b3a271a9SManish Rangankar exit_set_param_no_free: 1648b3a271a9SManish Rangankar return rval; 1649b3a271a9SManish Rangankar } 1650b3a271a9SManish Rangankar 1651b3a271a9SManish Rangankar int qla4xxx_get_mgmt_data(struct scsi_qla_host *ha, uint16_t fw_ddb_index, 1652b3a271a9SManish Rangankar uint16_t stats_size, dma_addr_t stats_dma) 1653b3a271a9SManish Rangankar { 1654b3a271a9SManish Rangankar int status = QLA_SUCCESS; 1655b3a271a9SManish Rangankar uint32_t mbox_cmd[MBOX_REG_COUNT]; 1656b3a271a9SManish Rangankar uint32_t mbox_sts[MBOX_REG_COUNT]; 1657b3a271a9SManish Rangankar 1658b3a271a9SManish Rangankar memset(mbox_cmd, 0, sizeof(mbox_cmd[0]) * MBOX_REG_COUNT); 1659b3a271a9SManish Rangankar memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT); 1660b3a271a9SManish Rangankar mbox_cmd[0] = MBOX_CMD_GET_MANAGEMENT_DATA; 1661b3a271a9SManish Rangankar mbox_cmd[1] = fw_ddb_index; 1662b3a271a9SManish Rangankar mbox_cmd[2] = LSDW(stats_dma); 1663b3a271a9SManish Rangankar mbox_cmd[3] = MSDW(stats_dma); 1664b3a271a9SManish Rangankar mbox_cmd[4] = stats_size; 1665b3a271a9SManish Rangankar 1666b3a271a9SManish Rangankar status = qla4xxx_mailbox_command(ha, 5, 1, &mbox_cmd[0], &mbox_sts[0]); 1667b3a271a9SManish Rangankar if (status != QLA_SUCCESS) { 1668b3a271a9SManish Rangankar DEBUG2(ql4_printk(KERN_WARNING, ha, 1669b3a271a9SManish Rangankar "%s: MBOX_CMD_GET_MANAGEMENT_DATA " 1670b3a271a9SManish Rangankar "failed w/ status %04X\n", __func__, 1671b3a271a9SManish Rangankar mbox_sts[0])); 1672b3a271a9SManish Rangankar } 1673b3a271a9SManish Rangankar return status; 1674b3a271a9SManish Rangankar } 16758b0402e1SHarish Zunjarrao 16768b0402e1SHarish Zunjarrao int qla4xxx_get_ip_state(struct scsi_qla_host *ha, uint32_t acb_idx, 16778b0402e1SHarish Zunjarrao uint32_t ip_idx, uint32_t *sts) 16788b0402e1SHarish Zunjarrao { 16798b0402e1SHarish Zunjarrao uint32_t mbox_cmd[MBOX_REG_COUNT]; 16808b0402e1SHarish Zunjarrao uint32_t mbox_sts[MBOX_REG_COUNT]; 16818b0402e1SHarish Zunjarrao int status = QLA_SUCCESS; 16828b0402e1SHarish Zunjarrao 16838b0402e1SHarish Zunjarrao memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 16848b0402e1SHarish Zunjarrao memset(&mbox_sts, 0, sizeof(mbox_sts)); 16858b0402e1SHarish Zunjarrao mbox_cmd[0] = MBOX_CMD_GET_IP_ADDR_STATE; 16868b0402e1SHarish Zunjarrao mbox_cmd[1] = acb_idx; 16878b0402e1SHarish Zunjarrao mbox_cmd[2] = ip_idx; 16888b0402e1SHarish Zunjarrao 16898b0402e1SHarish Zunjarrao status = qla4xxx_mailbox_command(ha, 3, 8, &mbox_cmd[0], &mbox_sts[0]); 16908b0402e1SHarish Zunjarrao if (status != QLA_SUCCESS) { 16918b0402e1SHarish Zunjarrao DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: " 16928b0402e1SHarish Zunjarrao "MBOX_CMD_GET_IP_ADDR_STATE failed w/ " 16938b0402e1SHarish Zunjarrao "status %04X\n", __func__, mbox_sts[0])); 16948b0402e1SHarish Zunjarrao } 16958b0402e1SHarish Zunjarrao memcpy(sts, mbox_sts, sizeof(mbox_sts)); 16968b0402e1SHarish Zunjarrao return status; 16978b0402e1SHarish Zunjarrao } 16987c07d139SHarish Zunjarrao 16997c07d139SHarish Zunjarrao int qla4xxx_get_nvram(struct scsi_qla_host *ha, dma_addr_t nvram_dma, 17007c07d139SHarish Zunjarrao uint32_t offset, uint32_t size) 17017c07d139SHarish Zunjarrao { 17027c07d139SHarish Zunjarrao int status = QLA_SUCCESS; 17037c07d139SHarish Zunjarrao uint32_t mbox_cmd[MBOX_REG_COUNT]; 17047c07d139SHarish Zunjarrao uint32_t mbox_sts[MBOX_REG_COUNT]; 17057c07d139SHarish Zunjarrao 17067c07d139SHarish Zunjarrao memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 17077c07d139SHarish Zunjarrao memset(&mbox_sts, 0, sizeof(mbox_sts)); 17087c07d139SHarish Zunjarrao 17097c07d139SHarish Zunjarrao mbox_cmd[0] = MBOX_CMD_GET_NVRAM; 17107c07d139SHarish Zunjarrao mbox_cmd[1] = LSDW(nvram_dma); 17117c07d139SHarish Zunjarrao mbox_cmd[2] = MSDW(nvram_dma); 17127c07d139SHarish Zunjarrao mbox_cmd[3] = offset; 17137c07d139SHarish Zunjarrao mbox_cmd[4] = size; 17147c07d139SHarish Zunjarrao 17157c07d139SHarish Zunjarrao status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], 17167c07d139SHarish Zunjarrao &mbox_sts[0]); 17177c07d139SHarish Zunjarrao if (status != QLA_SUCCESS) { 17187c07d139SHarish Zunjarrao DEBUG2(ql4_printk(KERN_ERR, ha, "scsi%ld: %s: failed " 17197c07d139SHarish Zunjarrao "status %04X\n", ha->host_no, __func__, 17207c07d139SHarish Zunjarrao mbox_sts[0])); 17217c07d139SHarish Zunjarrao } 17227c07d139SHarish Zunjarrao return status; 17237c07d139SHarish Zunjarrao } 17247c07d139SHarish Zunjarrao 17257c07d139SHarish Zunjarrao int qla4xxx_set_nvram(struct scsi_qla_host *ha, dma_addr_t nvram_dma, 17267c07d139SHarish Zunjarrao uint32_t offset, uint32_t size) 17277c07d139SHarish Zunjarrao { 17287c07d139SHarish Zunjarrao int status = QLA_SUCCESS; 17297c07d139SHarish Zunjarrao uint32_t mbox_cmd[MBOX_REG_COUNT]; 17307c07d139SHarish Zunjarrao uint32_t mbox_sts[MBOX_REG_COUNT]; 17317c07d139SHarish Zunjarrao 17327c07d139SHarish Zunjarrao memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 17337c07d139SHarish Zunjarrao memset(&mbox_sts, 0, sizeof(mbox_sts)); 17347c07d139SHarish Zunjarrao 17357c07d139SHarish Zunjarrao mbox_cmd[0] = MBOX_CMD_SET_NVRAM; 17367c07d139SHarish Zunjarrao mbox_cmd[1] = LSDW(nvram_dma); 17377c07d139SHarish Zunjarrao mbox_cmd[2] = MSDW(nvram_dma); 17387c07d139SHarish Zunjarrao mbox_cmd[3] = offset; 17397c07d139SHarish Zunjarrao mbox_cmd[4] = size; 17407c07d139SHarish Zunjarrao 17417c07d139SHarish Zunjarrao status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], 17427c07d139SHarish Zunjarrao &mbox_sts[0]); 17437c07d139SHarish Zunjarrao if (status != QLA_SUCCESS) { 17447c07d139SHarish Zunjarrao DEBUG2(ql4_printk(KERN_ERR, ha, "scsi%ld: %s: failed " 17457c07d139SHarish Zunjarrao "status %04X\n", ha->host_no, __func__, 17467c07d139SHarish Zunjarrao mbox_sts[0])); 17477c07d139SHarish Zunjarrao } 17487c07d139SHarish Zunjarrao return status; 17497c07d139SHarish Zunjarrao } 17505232f801SHarish Zunjarrao 17515232f801SHarish Zunjarrao int qla4xxx_restore_factory_defaults(struct scsi_qla_host *ha, 17525232f801SHarish Zunjarrao uint32_t region, uint32_t field0, 17535232f801SHarish Zunjarrao uint32_t field1) 17545232f801SHarish Zunjarrao { 17555232f801SHarish Zunjarrao int status = QLA_SUCCESS; 17565232f801SHarish Zunjarrao uint32_t mbox_cmd[MBOX_REG_COUNT]; 17575232f801SHarish Zunjarrao uint32_t mbox_sts[MBOX_REG_COUNT]; 17585232f801SHarish Zunjarrao 17595232f801SHarish Zunjarrao memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 17605232f801SHarish Zunjarrao memset(&mbox_sts, 0, sizeof(mbox_sts)); 17615232f801SHarish Zunjarrao 17625232f801SHarish Zunjarrao mbox_cmd[0] = MBOX_CMD_RESTORE_FACTORY_DEFAULTS; 17635232f801SHarish Zunjarrao mbox_cmd[3] = region; 17645232f801SHarish Zunjarrao mbox_cmd[4] = field0; 17655232f801SHarish Zunjarrao mbox_cmd[5] = field1; 17665232f801SHarish Zunjarrao 17675232f801SHarish Zunjarrao status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 3, &mbox_cmd[0], 17685232f801SHarish Zunjarrao &mbox_sts[0]); 17695232f801SHarish Zunjarrao if (status != QLA_SUCCESS) { 17705232f801SHarish Zunjarrao DEBUG2(ql4_printk(KERN_ERR, ha, "scsi%ld: %s: failed " 17715232f801SHarish Zunjarrao "status %04X\n", ha->host_no, __func__, 17725232f801SHarish Zunjarrao mbox_sts[0])); 17735232f801SHarish Zunjarrao } 17745232f801SHarish Zunjarrao return status; 17755232f801SHarish Zunjarrao } 1776