scsi: qla2xxx: Add SLER and PI control support

BIT_13 of extended FW attribute informs about NVMe-2 support.  Set BIT_15
of special feature control block for enabling SLER in FW.  Set bit 8 (SLER
supported) to 1 for the service parameter information when sending NVMe
PRLI request.  Set BIT_14 of special feature control block for enabling PI
Control in FW.  Driver should set bit 9 (PI Control supported) to 1 for the
service parameter information when sending NVMe PRLI request.  Set BIT_13
for NVMe Async events.

Link: https://lore.kernel.org/r/20200904045128.23631-13-njavali@marvell.com
Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
Signed-off-by: Saurav Kashyap <skashyap@marvell.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Saurav Kashyap 2020-09-03 21:51:27 -07:00 committed by Martin K. Petersen
parent 89c72f4245
commit cf3c54fb49
7 changed files with 45 additions and 5 deletions

View File

@ -16,7 +16,7 @@
* | Device Discovery | 0x2134 | 0x210e-0x2116 | * | Device Discovery | 0x2134 | 0x210e-0x2116 |
* | | | 0x211a | * | | | 0x211a |
* | | | 0x211c-0x2128 | * | | | 0x211c-0x2128 |
* | | | 0x212a-0x2134 | * | | | 0x212c-0x2134 |
* | Queue Command and IO tracing | 0x3074 | 0x300b | * | Queue Command and IO tracing | 0x3074 | 0x300b |
* | | | 0x3027-0x3028 | * | | | 0x3027-0x3028 |
* | | | 0x303d-0x3041 | * | | | 0x303d-0x3041 |

View File

@ -2476,6 +2476,8 @@ typedef struct fc_port {
struct completion nvme_del_done; struct completion nvme_del_done;
uint32_t nvme_prli_service_param; uint32_t nvme_prli_service_param;
#define NVME_PRLI_SP_PI_CTRL BIT_9
#define NVME_PRLI_SP_SLER BIT_8
#define NVME_PRLI_SP_CONF BIT_7 #define NVME_PRLI_SP_CONF BIT_7
#define NVME_PRLI_SP_INITIATOR BIT_5 #define NVME_PRLI_SP_INITIATOR BIT_5
#define NVME_PRLI_SP_TARGET BIT_4 #define NVME_PRLI_SP_TARGET BIT_4
@ -4309,6 +4311,7 @@ struct qla_hw_data {
#define FW_ATTR_EXT0_SCM_BROCADE 0x00001000 #define FW_ATTR_EXT0_SCM_BROCADE 0x00001000
/* Cisco fabric attached */ /* Cisco fabric attached */
#define FW_ATTR_EXT0_SCM_CISCO 0x00002000 #define FW_ATTR_EXT0_SCM_CISCO 0x00002000
#define FW_ATTR_EXT0_NVME2 BIT_13
uint16_t fw_attributes_ext[2]; uint16_t fw_attributes_ext[2];
uint32_t fw_memory_size; uint32_t fw_memory_size;
uint32_t fw_transfer_size; uint32_t fw_transfer_size;
@ -4658,6 +4661,7 @@ typedef struct scsi_qla_host {
uint32_t qpairs_rsp_created:1; uint32_t qpairs_rsp_created:1;
uint32_t nvme_enabled:1; uint32_t nvme_enabled:1;
uint32_t nvme_first_burst:1; uint32_t nvme_first_burst:1;
uint32_t nvme2_enabled:1;
} flags; } flags;
atomic_t loop_state; atomic_t loop_state;

View File

@ -2378,6 +2378,14 @@ qla24xx_prli_iocb(srb_t *sp, struct logio_entry_24xx *logio)
if (sp->vha->flags.nvme_first_burst) if (sp->vha->flags.nvme_first_burst)
logio->io_parameter[0] = logio->io_parameter[0] =
cpu_to_le32(NVME_PRLI_SP_FIRST_BURST); cpu_to_le32(NVME_PRLI_SP_FIRST_BURST);
if (sp->vha->flags.nvme2_enabled) {
/* Set service parameter BIT_8 for SLER support */
logio->io_parameter[0] |=
cpu_to_le32(NVME_PRLI_SP_SLER);
/* Set service parameter BIT_9 for PI control support */
logio->io_parameter[0] |=
cpu_to_le32(NVME_PRLI_SP_PI_CTRL);
}
} }
logio->nport_handle = cpu_to_le16(sp->fcport->loop_id); logio->nport_handle = cpu_to_le16(sp->fcport->loop_id);

View File

@ -1093,6 +1093,14 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha)
"%s: FC-NVMe is Enabled (0x%x)\n", "%s: FC-NVMe is Enabled (0x%x)\n",
__func__, ha->fw_attributes_h); __func__, ha->fw_attributes_h);
} }
/* BIT_13 of Extended FW Attributes informs about NVMe2 support */
if (ha->fw_attributes_ext[0] & FW_ATTR_EXT0_NVME2) {
ql_log(ql_log_info, vha, 0xd302,
"Firmware supports NVMe2 0x%x\n",
ha->fw_attributes_ext[0]);
vha->flags.nvme2_enabled = 1;
}
} }
if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
@ -1122,12 +1130,18 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha)
if (ha->flags.scm_supported_a && if (ha->flags.scm_supported_a &&
(ha->fw_attributes_ext[0] & FW_ATTR_EXT0_SCM_SUPPORTED)) { (ha->fw_attributes_ext[0] & FW_ATTR_EXT0_SCM_SUPPORTED)) {
ha->flags.scm_supported_f = 1; ha->flags.scm_supported_f = 1;
memset(ha->sf_init_cb, 0, sizeof(struct init_sf_cb));
ha->sf_init_cb->flags |= BIT_13; ha->sf_init_cb->flags |= BIT_13;
} }
ql_log(ql_log_info, vha, 0x11a3, "SCM in FW: %s\n", ql_log(ql_log_info, vha, 0x11a3, "SCM in FW: %s\n",
(ha->flags.scm_supported_f) ? "Supported" : (ha->flags.scm_supported_f) ? "Supported" :
"Not Supported"); "Not Supported");
if (vha->flags.nvme2_enabled) {
/* set BIT_15 of special feature control block for SLER */
ha->sf_init_cb->flags |= BIT_15;
/* set BIT_14 of special feature control block for PI CTRL*/
ha->sf_init_cb->flags |= BIT_14;
}
} }
failed: failed:
@ -1823,7 +1837,7 @@ qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
mcp->out_mb |= MBX_14|MBX_13|MBX_12|MBX_11|MBX_10; mcp->out_mb |= MBX_14|MBX_13|MBX_12|MBX_11|MBX_10;
} }
if (ha->flags.scm_supported_f) { if (ha->flags.scm_supported_f || vha->flags.nvme2_enabled) {
mcp->mb[1] |= BIT_1; mcp->mb[1] |= BIT_1;
mcp->mb[16] = MSW(ha->sf_init_cb_dma); mcp->mb[16] = MSW(ha->sf_init_cb_dma);
mcp->mb[17] = LSW(ha->sf_init_cb_dma); mcp->mb[17] = LSW(ha->sf_init_cb_dma);

View File

@ -69,6 +69,14 @@ int qla_nvme_register_remote(struct scsi_qla_host *vha, struct fc_port *fcport)
return ret; return ret;
} }
if (fcport->nvme_prli_service_param & NVME_PRLI_SP_SLER)
ql_log(ql_log_info, vha, 0x212a,
"PortID:%06x Supports SLER\n", req.port_id);
if (fcport->nvme_prli_service_param & NVME_PRLI_SP_PI_CTRL)
ql_log(ql_log_info, vha, 0x212b,
"PortID:%06x Supports PI control\n", req.port_id);
rport = fcport->nvme_remote_port->private; rport = fcport->nvme_remote_port->private;
rport->fcport = fcport; rport->fcport = fcport;
@ -368,6 +376,7 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp)
struct srb_iocb *nvme = &sp->u.iocb_cmd; struct srb_iocb *nvme = &sp->u.iocb_cmd;
struct scatterlist *sgl, *sg; struct scatterlist *sgl, *sg;
struct nvmefc_fcp_req *fd = nvme->u.nvme.desc; struct nvmefc_fcp_req *fd = nvme->u.nvme.desc;
struct nvme_fc_cmd_iu *cmd = fd->cmdaddr;
uint32_t rval = QLA_SUCCESS; uint32_t rval = QLA_SUCCESS;
/* Setup qpair pointers */ /* Setup qpair pointers */
@ -399,8 +408,6 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp)
} }
if (unlikely(!fd->sqid)) { if (unlikely(!fd->sqid)) {
struct nvme_fc_cmd_iu *cmd = fd->cmdaddr;
if (cmd->sqe.common.opcode == nvme_admin_async_event) { if (cmd->sqe.common.opcode == nvme_admin_async_event) {
nvme->u.nvme.aen_op = 1; nvme->u.nvme.aen_op = 1;
atomic_inc(&ha->nvme_active_aen_cnt); atomic_inc(&ha->nvme_active_aen_cnt);
@ -446,6 +453,11 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp)
} else if (fd->io_dir == 0) { } else if (fd->io_dir == 0) {
cmd_pkt->control_flags = 0; cmd_pkt->control_flags = 0;
} }
/* Set BIT_13 of control flags for Async event */
if (vha->flags.nvme2_enabled &&
cmd->sqe.common.opcode == nvme_admin_async_event) {
cmd_pkt->control_flags |= cpu_to_le16(CF_ADMIN_ASYNC_EVENT);
}
/* Set NPORT-ID */ /* Set NPORT-ID */
cmd_pkt->nport_handle = cpu_to_le16(sp->fcport->loop_id); cmd_pkt->nport_handle = cpu_to_le16(sp->fcport->loop_id);

View File

@ -54,6 +54,7 @@ struct cmd_nvme {
uint64_t rsvd; uint64_t rsvd;
__le16 control_flags; /* Control Flags */ __le16 control_flags; /* Control Flags */
#define CF_ADMIN_ASYNC_EVENT BIT_13
#define CF_NVME_FIRST_BURST_ENABLE BIT_11 #define CF_NVME_FIRST_BURST_ENABLE BIT_11
#define CF_DIF_SEG_DESCR_ENABLE BIT_3 #define CF_DIF_SEG_DESCR_ENABLE BIT_3
#define CF_DATA_SEG_DESCR_ENABLE BIT_2 #define CF_DATA_SEG_DESCR_ENABLE BIT_2

View File

@ -4231,6 +4231,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
&ha->sf_init_cb_dma); &ha->sf_init_cb_dma);
if (!ha->sf_init_cb) if (!ha->sf_init_cb)
goto fail_sf_init_cb; goto fail_sf_init_cb;
memset(ha->sf_init_cb, 0, sizeof(struct init_sf_cb));
ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0199, ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0199,
"sf_init_cb=%p.\n", ha->sf_init_cb); "sf_init_cb=%p.\n", ha->sf_init_cb);
} }