Commit d3bae931 authored by Duane Grigsby's avatar Duane Grigsby Committed by Martin K. Petersen

scsi: qla2xxx: Send FC4 type NVMe to the management server

This patch adds switch command support for FC-4 type of FC-NVMe (0x28)
for resgistering HBA port to the management server. RFT_ID command is
used to register FC-4 type of 0x28 and RFF_ID is used to register FC-4
features bits for FC-NVMe port.
Signed-off-by: default avatarDarren Trapp <darren.trapp@cavium.com>
Signed-off-by: default avatarDuane Grigsby <duane.grigsby@cavium.com>
Signed-off-by: default avatarAnil Gurumurthy <anil.gurumurhty@cavium.com>
Signed-off-by: default avatarGiridhar Malavali <giridhar.malavali@cavium.com>
Signed-off-by: default avatarHimanshu Madhani <himanshu.madhani@cavium.com>
Reviewed-By: default avatarJames Smart <james.smart@broadcom.com>
Reviewed-by: default avatarHannes Reinecke <hare@suse.com>
Reviewed-by: default avatarJohannes Thumshirn <jthumshirn@suse.de>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent e84067d7
......@@ -2867,6 +2867,7 @@ struct ct_sns_rsp {
} gpsc;
#define GFF_FCP_SCSI_OFFSET 7
#define GFF_NVME_OFFSET 23 /* type = 28h */
struct {
uint8_t fc4_features[128];
} gff_id;
......
......@@ -18,6 +18,7 @@ extern void qla_nvme_delete(scsi_qla_host_t *);
extern void qla_nvme_abort(struct qla_hw_data *, srb_t *sp);
extern void qla24xx_nvme_ls4_iocb(scsi_qla_host_t *, struct pt_ls4_request *,
struct req_que *);
extern void qla24xx_async_gffid_sp_done(void *, int);
/*
* Global Function Prototypes in qla_init.c source file.
......@@ -618,7 +619,7 @@ extern int qla2x00_gpn_id(scsi_qla_host_t *, sw_info_t *);
extern int qla2x00_gnn_id(scsi_qla_host_t *, sw_info_t *);
extern void qla2x00_gff_id(scsi_qla_host_t *, sw_info_t *);
extern int qla2x00_rft_id(scsi_qla_host_t *);
extern int qla2x00_rff_id(scsi_qla_host_t *);
extern int qla2x00_rff_id(scsi_qla_host_t *, u8);
extern int qla2x00_rnn_id(scsi_qla_host_t *);
extern int qla2x00_rsnn_nn(scsi_qla_host_t *);
extern void *qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t);
......@@ -644,7 +645,8 @@ void qla24xx_handle_gpnid_event(scsi_qla_host_t *, struct event_arg *);
int qla24xx_post_gpsc_work(struct scsi_qla_host *, fc_port_t *);
int qla24xx_async_gpsc(scsi_qla_host_t *, fc_port_t *);
int qla2x00_mgmt_svr_login(scsi_qla_host_t *);
void qla24xx_handle_gffid_event(scsi_qla_host_t *vha, struct event_arg *ea);
int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport);
/*
* Global Function Prototypes in qla_attr.c source file.
*/
......
......@@ -550,6 +550,8 @@ qla2x00_rft_id(scsi_qla_host_t *vha)
ct_req->req.rft_id.fc4_types[2] = 0x01; /* FCP-3 */
if (vha->flags.nvme_enabled)
ct_req->req.rft_id.fc4_types[6] = 1; /* NVMe type 28h */
/* Execute MS IOCB */
rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
sizeof(ms_iocb_entry_t));
......@@ -575,7 +577,7 @@ qla2x00_rft_id(scsi_qla_host_t *vha)
* Returns 0 on success.
*/
int
qla2x00_rff_id(scsi_qla_host_t *vha)
qla2x00_rff_id(scsi_qla_host_t *vha, u8 type)
{
int rval;
struct qla_hw_data *ha = vha->hw;
......@@ -613,7 +615,7 @@ qla2x00_rff_id(scsi_qla_host_t *vha)
qlt_rff_id(vha, ct_req);
ct_req->req.rff_id.fc4_type = 0x08; /* SCSI - FCP */
ct_req->req.rff_id.fc4_type = type; /* SCSI - FCP */
/* Execute MS IOCB */
rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
......@@ -2754,6 +2756,10 @@ qla2x00_gff_id(scsi_qla_host_t *vha, sw_info_t *list)
list[i].fc4_type = FC4_TYPE_FCP_SCSI;
else
list[i].fc4_type = FC4_TYPE_OTHER;
list[i].fc4f_nvme =
ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET];
list[i].fc4f_nvme &= 0xf;
}
/* Last device exit. */
......@@ -3305,3 +3311,111 @@ int qla24xx_async_gpnid(scsi_qla_host_t *vha, port_id_t *id)
done:
return rval;
}
void qla24xx_handle_gffid_event(scsi_qla_host_t *vha, struct event_arg *ea)
{
fc_port_t *fcport = ea->fcport;
qla24xx_post_gnl_work(vha, fcport);
}
void qla24xx_async_gffid_sp_done(void *s, int res)
{
struct srb *sp = s;
struct scsi_qla_host *vha = sp->vha;
fc_port_t *fcport = sp->fcport;
struct ct_sns_rsp *ct_rsp;
struct event_arg ea;
ql_dbg(ql_dbg_disc, vha, 0x2133,
"Async done-%s res %x ID %x. %8phC\n",
sp->name, res, fcport->d_id.b24, fcport->port_name);
fcport->flags &= ~FCF_ASYNC_SENT;
ct_rsp = &fcport->ct_desc.ct_sns->p.rsp;
/*
* FC-GS-7, 5.2.3.12 FC-4 Features - format
* The format of the FC-4 Features object, as defined by the FC-4,
* Shall be an array of 4-bit values, one for each type code value
*/
if (!res) {
if (ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET] & 0xf) {
/* w1 b00:03 */
fcport->fc4_type =
ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET];
fcport->fc4_type &= 0xf;
}
if (ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET] & 0xf) {
/* w5 [00:03]/28h */
fcport->fc4f_nvme =
ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET];
fcport->fc4f_nvme &= 0xf;
}
}
memset(&ea, 0, sizeof(ea));
ea.sp = sp;
ea.fcport = sp->fcport;
ea.rc = res;
ea.event = FCME_GFFID_DONE;
qla2x00_fcport_event_handler(vha, &ea);
sp->free(sp);
}
/* Get FC4 Feature with Nport ID. */
int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport)
{
int rval = QLA_FUNCTION_FAILED;
struct ct_sns_req *ct_req;
srb_t *sp;
if (!vha->flags.online)
return rval;
sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
if (!sp)
return rval;
fcport->flags |= FCF_ASYNC_SENT;
sp->type = SRB_CT_PTHRU_CMD;
sp->name = "gffid";
sp->gen1 = fcport->rscn_gen;
sp->gen2 = fcport->login_gen;
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
/* CT_IU preamble */
ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GFF_ID_CMD,
GFF_ID_RSP_SIZE);
ct_req->req.gff_id.port_id[0] = fcport->d_id.b.domain;
ct_req->req.gff_id.port_id[1] = fcport->d_id.b.area;
ct_req->req.gff_id.port_id[2] = fcport->d_id.b.al_pa;
sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns;
sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma;
sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns;
sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma;
sp->u.iocb_cmd.u.ctarg.req_size = GFF_ID_REQ_SIZE;
sp->u.iocb_cmd.u.ctarg.rsp_size = GFF_ID_RSP_SIZE;
sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
sp->done = qla24xx_async_gffid_sp_done;
rval = qla2x00_start_sp(sp);
if (rval != QLA_SUCCESS)
goto done_free_sp;
ql_dbg(ql_dbg_disc, vha, 0x2132,
"Async-%s hdl=%x %8phC.\n", sp->name,
sp->handle, fcport->port_name);
return rval;
done_free_sp:
sp->free(sp);
fcport->flags &= ~FCF_ASYNC_SENT;
return rval;
}
......@@ -1244,6 +1244,9 @@ void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea)
case FCME_GPNID_DONE:
qla24xx_handle_gpnid_event(vha, ea);
break;
case FCME_GFFID_DONE:
qla24xx_handle_gffid_event(vha, ea);
break;
case FCME_DELETE_DONE:
qla24xx_handle_delete_done_event(vha, ea);
break;
......@@ -4633,7 +4636,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)
&vha->dpc_flags))
break;
}
if (qla2x00_rff_id(vha)) {
if (qla2x00_rff_id(vha, FC4_TYPE_FCP_SCSI)) {
/* EMPTY */
ql_dbg(ql_dbg_disc, vha, 0x209a,
"Register FC-4 Features failed.\n");
......@@ -4641,6 +4644,12 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)
&vha->dpc_flags))
break;
}
if (vha->flags.nvme_enabled) {
if (qla2x00_rff_id(vha, FC_TYPE_NVME)) {
ql_dbg(ql_dbg_disc, vha, 0x2049,
"Register NVME FC Type Features failed.\n");
}
}
if (qla2x00_rnn_id(vha)) {
/* EMPTY */
ql_dbg(ql_dbg_disc, vha, 0x2104,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment