diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_mbx.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 59 |
1 files changed, 52 insertions, 7 deletions
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 9f3ad8aa649c..7811c4952035 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -663,6 +663,7 @@ qla2x00_load_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t risc_addr, } #define NVME_ENABLE_FLAG BIT_3 +#define EDIF_HW_SUPPORT BIT_10 /* * qla2x00_execute_fw @@ -739,7 +740,7 @@ again: mcp->mb[11] |= EXE_FW_FORCE_SEMAPHORE; mcp->out_mb |= MBX_4 | MBX_3 | MBX_2 | MBX_1 | MBX_11; - mcp->in_mb |= MBX_3 | MBX_2 | MBX_1; + mcp->in_mb |= MBX_5 | MBX_3 | MBX_2 | MBX_1; } else { mcp->mb[1] = LSW(risc_addr); mcp->out_mb |= MBX_1; @@ -795,6 +796,12 @@ again: } } + if (IS_QLA28XX(ha) && (mcp->mb[5] & EDIF_HW_SUPPORT)) { + ha->flags.edif_hw = 1; + ql_log(ql_log_info, vha, 0xffff, + "%s: edif HW\n", __func__); + } + done: ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1028, "Done %s.\n", __func__); @@ -1130,6 +1137,13 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha) ha->fw_attributes_ext[0]); vha->flags.nvme2_enabled = 1; } + + if (IS_QLA28XX(ha) && ha->flags.edif_hw && ql2xsecenable && + (ha->fw_attributes_ext[0] & FW_ATTR_EXT0_EDIF)) { + ha->flags.edif_enabled = 1; + ql_log(ql_log_info, vha, 0xffff, + "%s: edif is enabled\n", __func__); + } } if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { @@ -3231,7 +3245,7 @@ qla24xx_abort_command(srb_t *sp) if (sp->qpair) req = sp->qpair->req; else - return QLA_FUNCTION_FAILED; + return QLA_ERR_NO_QPAIR; if (ql2xasynctmfenable) return qla24xx_async_abort_command(sp); @@ -3244,7 +3258,7 @@ qla24xx_abort_command(srb_t *sp) spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); if (handle == req->num_outstanding_cmds) { /* Command not found. */ - return QLA_FUNCTION_FAILED; + return QLA_ERR_NOT_FOUND; } abt = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &abt_dma); @@ -4035,6 +4049,10 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, fcport->scan_state = QLA_FCPORT_FOUND; fcport->n2n_flag = 1; fcport->keep_nport_handle = 1; + fcport->login_retry = vha->hw->login_retry_count; + fcport->fc4_type = FS_FC4TYPE_FCP; + if (vha->flags.nvme_enabled) + fcport->fc4_type |= FS_FC4TYPE_NVME; if (wwn_to_u64(vha->port_name) > wwn_to_u64(fcport->port_name)) { @@ -4172,6 +4190,16 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, rptid_entry->u.f2.remote_nport_id[1]; fcport->d_id.b.al_pa = rptid_entry->u.f2.remote_nport_id[0]; + + /* + * For the case where remote port sending PRLO, FW + * sends up RIDA Format 2 as an indication of session + * loss. In other word, FW state change from PRLI + * complete back to PLOGI complete. Delete the + * session and let relogin drive the reconnect. + */ + if (atomic_read(&fcport->state) == FCS_ONLINE) + qlt_schedule_sess_for_deletion(fcport); } } } @@ -4946,7 +4974,7 @@ qla24xx_get_port_login_templ(scsi_qla_host_t *vha, dma_addr_t buf_dma, return rval; } -#define PUREX_CMD_COUNT 2 +#define PUREX_CMD_COUNT 4 int qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha) { @@ -4954,6 +4982,7 @@ qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha) mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; uint8_t *els_cmd_map; + uint8_t active_cnt = 0; dma_addr_t els_cmd_map_dma; uint8_t cmd_opcode[PUREX_CMD_COUNT]; uint8_t i, index, purex_bit; @@ -4975,10 +5004,20 @@ qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha) } /* List of Purex ELS */ - cmd_opcode[0] = ELS_FPIN; - cmd_opcode[1] = ELS_RDP; + if (ql2xrdpenable) { + cmd_opcode[active_cnt] = ELS_RDP; + active_cnt++; + } + if (ha->flags.scm_supported_f) { + cmd_opcode[active_cnt] = ELS_FPIN; + active_cnt++; + } + if (ha->flags.edif_enabled) { + cmd_opcode[active_cnt] = ELS_AUTH_ELS; + active_cnt++; + } - for (i = 0; i < PUREX_CMD_COUNT; i++) { + for (i = 0; i < active_cnt; i++) { index = cmd_opcode[i] / 8; purex_bit = cmd_opcode[i] % 8; els_cmd_map[index] |= 1 << purex_bit; @@ -6588,6 +6627,12 @@ int __qla24xx_parse_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport, fcport->d_id.b.al_pa = pd->port_id[2]; fcport->d_id.b.rsvd_1 = 0; + ql_dbg(ql_dbg_disc, vha, 0x2062, + "%8phC SVC Param w3 %02x%02x", + fcport->port_name, + pd->prli_svc_param_word_3[1], + pd->prli_svc_param_word_3[0]); + if (NVME_TARGET(vha->hw, fcport)) { fcport->port_type = FCT_NVME; if ((pd->prli_svc_param_word_3[0] & BIT_5) == 0) |