On 5/31/21 9:05 AM, Nilesh Javali wrote: > From: Quinn Tran <qutran@xxxxxxxxxxx> > > Latest FC adapter from Marvell has the ability to encrypt > data in flight (EDIF) feature. This feature require an > application (ex: ipsec, etc) to act as an authenticator. > > This patch add 2 new BSG calls: > QL_VND_SC_GET_FCINFO: Application from time to time can request > for a list of all FC ports or a single device that support > secure connection. If driver sees a new or old device has > came onto the switch, this call is used to check for the WWPN. > > QL_VND_SC_GET_STATS: Application request for various statistic > count of each FC port. > > Signed-off-by: Larry Wisneski <Larry.Wisneski@xxxxxxxxxxx> > Signed-off-by: Duane Grigsby <duane.grigsby@xxxxxxxxxxx> > Signed-off-by: Rick Hicksted Jr <rhicksted@xxxxxxxxxxx> > Signed-off-by: Quinn Tran <qutran@xxxxxxxxxxx> > Signed-off-by: Nilesh Javali <njavali@xxxxxxxxxxx> > --- > drivers/scsi/qla2xxx/qla_def.h | 2 + > drivers/scsi/qla2xxx/qla_edif.c | 182 ++++++++++++++++++++++++++++++++ > 2 files changed, 184 insertions(+) > > diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h > index ac3b9b39d741..9c921381d020 100644 > --- a/drivers/scsi/qla2xxx/qla_def.h > +++ b/drivers/scsi/qla2xxx/qla_def.h > @@ -2574,6 +2574,8 @@ typedef struct fc_port { > uint16_t app_started:1; > uint16_t secured_login:1; > uint16_t app_sess_online:1; > + uint16_t rekey_cnt; // num of times rekeyed > + uint8_t auth_state; /* cureent auth state */ > uint32_t tx_rekey_cnt; > uint32_t rx_rekey_cnt; > // delayed rx delete data structure list Please check structure alignment. > diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c > index 38d79ef2e700..fd39232fa68d 100644 > --- a/drivers/scsi/qla2xxx/qla_edif.c > +++ b/drivers/scsi/qla2xxx/qla_edif.c > @@ -258,6 +258,182 @@ qla_edif_app_stop(scsi_qla_host_t *vha, struct bsg_job *bsg_job) > return rval; > } > > +/* > + * event that the app needs fc port info (either all or individual d_id) > + */ > +static int > +qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job) > +{ > + int32_t rval = 0; > + int32_t num_cnt = 1; > + struct fc_bsg_reply *bsg_reply = bsg_job->reply; > + struct app_pinfo_req app_req; > + struct app_pinfo_reply *app_reply; > + port_id_t tdid; > + > + ql_dbg(ql_dbg_edif, vha, 0x911d, "%s app get fcinfo\n", __func__); > + > + sg_copy_to_buffer(bsg_job->request_payload.sg_list, > + bsg_job->request_payload.sg_cnt, &app_req, > + sizeof(struct app_pinfo_req)); > + > + num_cnt = app_req.num_ports; /* num of ports alloc'd by app */ > + > + app_reply = kzalloc((sizeof(struct app_pinfo_reply) + > + sizeof(struct app_pinfo) * num_cnt), GFP_KERNEL); > + if (!app_reply) { > + SET_DID_STATUS(bsg_reply->result, DID_ERROR); > + rval = -1; > + } else { > + struct fc_port *fcport = NULL, *tf; > + uint32_t pcnt = 0; > + > + list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) { > + if (!(fcport->flags & FCF_FCSP_DEVICE)) > + continue; > + > + tdid = app_req.remote_pid; > + > + ql_dbg(ql_dbg_edif, vha, 0x2058, > + "APP request entry - portid=%02x%02x%02x.\n", > + tdid.b.domain, tdid.b.area, tdid.b.al_pa); > + > + /* Ran out of space */ > + if (pcnt > app_req.num_ports) > + break; > + > + if (tdid.b24 != 0 && tdid.b24 != fcport->d_id.b24) > + continue; > + > + app_reply->ports[pcnt].remote_type = > + VND_CMD_RTYPE_UNKNOWN; > + if (fcport->port_type & (FCT_NVME_TARGET | FCT_TARGET)) > + app_reply->ports[pcnt].remote_type |= > + VND_CMD_RTYPE_TARGET; > + if (fcport->port_type & (FCT_NVME_INITIATOR | FCT_INITIATOR)) > + app_reply->ports[pcnt].remote_type |= > + VND_CMD_RTYPE_INITIATOR; > + > + app_reply->ports[pcnt].remote_pid = fcport->d_id; > + > + ql_dbg(ql_dbg_edif, vha, 0x2058, > + "Found FC_SP fcport - nn %8phN pn %8phN pcnt %d portid=%02x%02x%02x.\n", Indentation. > + fcport->node_name, fcport->port_name, pcnt, > + fcport->d_id.b.domain, fcport->d_id.b.area, > + fcport->d_id.b.al_pa); > + > + switch (fcport->edif.auth_state) { > + case VND_CMD_AUTH_STATE_ELS_RCVD: > + if (fcport->disc_state == DSC_LOGIN_AUTH_PEND) { > + fcport->edif.auth_state = VND_CMD_AUTH_STATE_NEEDED; > + app_reply->ports[pcnt].auth_state = > + VND_CMD_AUTH_STATE_NEEDED; > + } else { > + app_reply->ports[pcnt].auth_state = > + VND_CMD_AUTH_STATE_ELS_RCVD; > + } > + break; > + default: > + app_reply->ports[pcnt].auth_state = fcport->edif.auth_state; > + break; > + } > + > + memcpy(app_reply->ports[pcnt].remote_wwpn, > + fcport->port_name, 8); > + > + app_reply->ports[pcnt].remote_state = > + (atomic_read(&fcport->state) == > + FCS_ONLINE ? 1 : 0); > + > + pcnt++; > + > + if (tdid.b24 != 0) > + break; /* found the one req'd */ > + } > + app_reply->port_count = pcnt; > + SET_DID_STATUS(bsg_reply->result, DID_OK); > + } > + > + sg_copy_from_buffer(bsg_job->reply_payload.sg_list, > + bsg_job->reply_payload.sg_cnt, app_reply, > + sizeof(struct app_pinfo_reply) + sizeof(struct app_pinfo) * num_cnt); > + > + kfree(app_reply); > + > + return rval; > +} > + > +/* > + * return edif stats (TBD) to app > + */ > +static int32_t > +qla_edif_app_getstats(scsi_qla_host_t *vha, struct bsg_job *bsg_job) > +{ > + int32_t rval = 0; > + struct fc_bsg_reply *bsg_reply = bsg_job->reply; > + uint32_t ret_size, size; > + > + struct app_sinfo_req app_req; > + struct app_stats_reply *app_reply; > + > + sg_copy_to_buffer(bsg_job->request_payload.sg_list, > + bsg_job->request_payload.sg_cnt, &app_req, > + sizeof(struct app_sinfo_req)); > + if (app_req.num_ports == 0) { > + ql_dbg(ql_dbg_async, vha, 0x911d, > + "%s app did not indicate number of ports to return\n", > + __func__); > + SET_DID_STATUS(bsg_reply->result, DID_ERROR); > + rval = -1; > + } > + > + size = sizeof(struct app_stats_reply) + > + (sizeof(struct app_sinfo) * app_req.num_ports); > + > + if (size > bsg_job->reply_payload.payload_len) > + ret_size = bsg_job->reply_payload.payload_len; > + else > + ret_size = size; > + > + app_reply = kzalloc(size, GFP_KERNEL); > + if (!app_reply) { > + SET_DID_STATUS(bsg_reply->result, DID_ERROR); > + rval = -1; > + } else { > + struct fc_port *fcport = NULL, *tf; > + uint32_t pcnt = 0; > + > + list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) { > + if (fcport->edif.enable) { > + if (pcnt > app_req.num_ports) > + break; > + > + app_reply->elem[pcnt].rekey_count = > + fcport->edif.rekey_cnt; > + app_reply->elem[pcnt].tx_bytes = > + fcport->edif.tx_bytes; > + app_reply->elem[pcnt].rx_bytes = > + fcport->edif.rx_bytes; > + > + memcpy(app_reply->elem[pcnt].remote_wwpn, > + fcport->port_name, 8); > + > + pcnt++; > + } > + } > + app_reply->elem_count = pcnt; > + SET_DID_STATUS(bsg_reply->result, DID_OK); > + } > + > + bsg_reply->reply_payload_rcv_len = > + sg_copy_from_buffer(bsg_job->reply_payload.sg_list, > + bsg_job->reply_payload.sg_cnt, app_reply, ret_size); > + > + kfree(app_reply); > + > + return rval; > +} > + > int32_t > qla_edif_app_mgmt(struct bsg_job *bsg_job) > { > @@ -304,6 +480,12 @@ qla_edif_app_mgmt(struct bsg_job *bsg_job) > case QL_VND_SC_APP_STOP: > rval = qla_edif_app_stop(vha, bsg_job); > break; > + case QL_VND_SC_GET_FCINFO: > + rval = qla_edif_app_getfcinfo(vha, bsg_job); > + break; > + case QL_VND_SC_GET_STATS: > + rval = qla_edif_app_getstats(vha, bsg_job); > + break; > default: > ql_dbg(ql_dbg_edif, vha, 0x911d, "%s unknown cmd=%x\n", > __func__, > Other than that: Reviewed-by: Hannes Reinecke <hare@xxxxxxx> Cheers, Hannes -- Dr. Hannes Reinecke Kernel Storage Architect hare@xxxxxxx +49 911 74053 688 SUSE Software Solutions Germany GmbH, 90409 Nürnberg GF: F. Imendörffer, HRB 36809 (AG Nürnberg)