On 12/20/19 11:36 PM, James Smart wrote: > This patch continues the libefc_sli SLI-4 library population. > > This patch adds service routines to create different WQEs and adds > APIs to issue iread, iwrite, treceive, tsend and other work queue > entries. > > Signed-off-by: Ram Vegesna <ram.vegesna@xxxxxxxxxxxx> > Signed-off-by: James Smart <jsmart2021@xxxxxxxxx> > --- > drivers/scsi/elx/libefc_sli/sli4.c | 1717 ++++++++++++++++++++++++++++++++++++ > drivers/scsi/elx/libefc_sli/sli4.h | 2 + > 2 files changed, 1719 insertions(+) > > diff --git a/drivers/scsi/elx/libefc_sli/sli4.c b/drivers/scsi/elx/libefc_sli/sli4.c > index 7061f7980fad..2ebe0235bc9e 100644 > --- a/drivers/scsi/elx/libefc_sli/sli4.c > +++ b/drivers/scsi/elx/libefc_sli/sli4.c > @@ -1580,3 +1580,1720 @@ sli_cq_parse(struct sli4 *sli4, struct sli4_queue *cq, u8 *cqe, > > return rc; > } > + > +/* Write an ABORT_WQE work queue entry */ > +int > +sli_abort_wqe(struct sli4 *sli4, void *buf, size_t size, > + enum sli4_abort_type type, bool send_abts, u32 ids, > + u32 mask, u16 tag, u16 cq_id) > +{ > + struct sli4_abort_wqe *abort = buf; > + > + memset(buf, 0, size); > + > + switch (type) { > + case SLI_ABORT_XRI: > + abort->criteria = SLI4_ABORT_CRITERIA_XRI_TAG; > + if (mask) { > + efc_log_warn(sli4, "%#x aborting XRI %#x warning non-zero mask", > + mask, ids); > + mask = 0; > + } > + break; > + case SLI_ABORT_ABORT_ID: > + abort->criteria = SLI4_ABORT_CRITERIA_ABORT_TAG; > + break; > + case SLI_ABORT_REQUEST_ID: > + abort->criteria = SLI4_ABORT_CRITERIA_REQUEST_TAG; > + break; > + default: > + efc_log_info(sli4, "unsupported type %#x\n", type); > + return EFC_FAIL; > + } > + > + abort->ia_ir_byte |= send_abts ? 0 : 1; > + > + /* Suppress ABTS retries */ > + abort->ia_ir_byte |= SLI4_ABRT_WQE_IR; > + > + abort->t_mask = cpu_to_le32(mask); > + abort->t_tag = cpu_to_le32(ids); > + abort->command = SLI4_WQE_ABORT; > + abort->request_tag = cpu_to_le16(tag); > + > + abort->dw10w0_flags = cpu_to_le16(SLI4_ABRT_WQE_QOSD); > + > + abort->cq_id = cpu_to_le16(cq_id); > + abort->cmdtype_wqec_byte |= SLI4_CMD_ABORT_WQE; > + > + return EFC_SUCCESS; > +} > + > +/* Write an ELS_REQUEST64_WQE work queue entry */ > +int > +sli_els_request64_wqe(struct sli4 *sli4, void *buf, size_t size, > + struct efc_dma *sgl, > + u8 req_type, u32 req_len, u32 max_rsp_len, > + u8 timeout, u16 xri, u16 tag, > + u16 cq_id, u16 rnodeindicator, u16 sportindicator, > + bool hlm, bool rnodeattached, u32 rnode_fcid, > + u32 sport_fcid) > +{ > + struct sli4_els_request64_wqe *els = buf; > + struct sli4_sge *sge = sgl->virt; > + bool is_fabric = false; > + struct sli4_bde *bptr; > + > + memset(buf, 0, size); > + > + bptr = &els->els_request_payload; > + if (sli4->sgl_pre_registered) { > + els->qosd_xbl_hlm_iod_dbde_wqes &= ~SLI4_REQ_WQE_XBL; > + > + els->qosd_xbl_hlm_iod_dbde_wqes |= SLI4_REQ_WQE_DBDE; > + bptr->bde_type_buflen = > + cpu_to_le32((BDE_TYPE_BDE_64 << BDE_TYPE_SHIFT) | > + (req_len & SLI4_BDE_MASK_BUFFER_LEN)); > + > + bptr->u.data.low = sge[0].buffer_address_low; > + bptr->u.data.high = sge[0].buffer_address_high; > + } else { > + els->qosd_xbl_hlm_iod_dbde_wqes |= SLI4_REQ_WQE_XBL; > + > + bptr->bde_type_buflen = > + cpu_to_le32((BDE_TYPE_BLP << BDE_TYPE_SHIFT) | > + ((2 * sizeof(struct sli4_sge)) & > + SLI4_BDE_MASK_BUFFER_LEN)); > + bptr->u.blp.low = cpu_to_le32(lower_32_bits(sgl->phys)); > + bptr->u.blp.high = cpu_to_le32(upper_32_bits(sgl->phys)); > + } > + > + els->els_request_payload_length = cpu_to_le32(req_len); > + els->max_response_payload_length = cpu_to_le32(max_rsp_len); > + > + els->xri_tag = cpu_to_le16(xri); > + els->timer = timeout; > + els->class_byte |= SLI4_GENERIC_CLASS_CLASS_3; > + > + els->command = SLI4_WQE_ELS_REQUEST64; > + > + els->request_tag = cpu_to_le16(tag); > + > + if (hlm) { > + els->qosd_xbl_hlm_iod_dbde_wqes |= SLI4_REQ_WQE_HLM; > + els->remote_id_dword = cpu_to_le32(rnode_fcid & 0x00ffffff); > + } > + > + els->qosd_xbl_hlm_iod_dbde_wqes |= SLI4_REQ_WQE_IOD; > + > + els->qosd_xbl_hlm_iod_dbde_wqes |= SLI4_REQ_WQE_QOSD; > + > + /* figure out the ELS_ID value from the request buffer */ > + > + switch (req_type) { > + case ELS_LOGO: > + els->cmdtype_elsid_byte |= > + SLI4_ELS_REQUEST64_LOGO << SLI4_REQ_WQE_ELSID_SHFT; > + if (rnodeattached) { > + els->ct_byte |= (SLI4_GENERIC_CONTEXT_RPI << > + SLI4_REQ_WQE_CT_SHFT); > + els->context_tag = cpu_to_le16(rnodeindicator); > + } else { > + els->ct_byte |= > + SLI4_GENERIC_CONTEXT_VPI << SLI4_REQ_WQE_CT_SHFT; > + els->context_tag = > + cpu_to_le16(sportindicator); > + } > + if (rnode_fcid == FC_FID_FLOGI) > + is_fabric = true; > + break; > + case ELS_FDISC: > + if (rnode_fcid == FC_FID_FLOGI) > + is_fabric = true; > + if (sport_fcid == 0) { > + els->cmdtype_elsid_byte |= > + SLI4_ELS_REQUEST64_FDISC << SLI4_REQ_WQE_ELSID_SHFT; > + is_fabric = true; > + } else { > + els->cmdtype_elsid_byte |= > + SLI4_ELS_REQUEST64_OTHER << SLI4_REQ_WQE_ELSID_SHFT; > + } > + els->ct_byte |= (SLI4_GENERIC_CONTEXT_VPI << > + SLI4_REQ_WQE_CT_SHFT); > + els->context_tag = cpu_to_le16(sportindicator); > + els->sid_sp_dword |= cpu_to_le32(1 << SLI4_REQ_WQE_SP_SHFT); > + break; > + case ELS_FLOGI: > + els->ct_byte |= > + SLI4_GENERIC_CONTEXT_VPI << SLI4_REQ_WQE_CT_SHFT; > + els->context_tag = cpu_to_le16(sportindicator); > + /* > + * Set SP here ... we haven't done a REG_VPI yet > + * need to maybe not set this when we have > + * completed VFI/VPI registrations ... > + * > + * Use the FC_ID of the SPORT if it has been allocated, > + * otherwise use an S_ID of zero. > + */ > + els->sid_sp_dword |= cpu_to_le32(1 << SLI4_REQ_WQE_SP_SHFT); > + if (sport_fcid != U32_MAX) > + els->sid_sp_dword |= cpu_to_le32(sport_fcid); > + break; > + case ELS_PLOGI: > + els->cmdtype_elsid_byte |= > + SLI4_ELS_REQUEST64_PLOGI << SLI4_REQ_WQE_ELSID_SHFT; > + els->ct_byte |= > + SLI4_GENERIC_CONTEXT_VPI << SLI4_REQ_WQE_CT_SHFT; > + els->context_tag = cpu_to_le16(sportindicator); > + break; > + case ELS_SCR: > + els->cmdtype_elsid_byte |= > + SLI4_ELS_REQUEST64_OTHER << SLI4_REQ_WQE_ELSID_SHFT; > + els->ct_byte |= > + SLI4_GENERIC_CONTEXT_VPI << SLI4_REQ_WQE_CT_SHFT; > + els->context_tag = cpu_to_le16(sportindicator); > + break; > + default: > + els->cmdtype_elsid_byte |= > + SLI4_ELS_REQUEST64_OTHER << SLI4_REQ_WQE_ELSID_SHFT; > + if (rnodeattached) { > + els->ct_byte |= (SLI4_GENERIC_CONTEXT_RPI << > + SLI4_REQ_WQE_CT_SHFT); > + els->context_tag = cpu_to_le16(sportindicator); > + } else { > + els->ct_byte |= > + SLI4_GENERIC_CONTEXT_VPI << SLI4_REQ_WQE_CT_SHFT; > + els->context_tag = > + cpu_to_le16(sportindicator); > + } > + break; > + } > + > + if (is_fabric) > + els->cmdtype_elsid_byte |= SLI4_ELS_REQUEST64_CMD_FABRIC; > + else > + els->cmdtype_elsid_byte |= SLI4_ELS_REQUEST64_CMD_NON_FABRIC; > + > + els->cq_id = cpu_to_le16(cq_id); > + > + if (((els->ct_byte & SLI4_REQ_WQE_CT) >> SLI4_REQ_WQE_CT_SHFT) != > + SLI4_GENERIC_CONTEXT_RPI) > + els->remote_id_dword = cpu_to_le32(rnode_fcid); > + > + if (((els->ct_byte & SLI4_REQ_WQE_CT) >> SLI4_REQ_WQE_CT_SHFT) == > + SLI4_GENERIC_CONTEXT_VPI) > + els->temporary_rpi = cpu_to_le16(rnodeindicator); > + > + return EFC_SUCCESS; > +} > + You seem to have given up using EFC_SUCCESS / EFC_FAIL for the next few functions. Please be consistent here. Cheers, Hannes -- Dr. Hannes Reinecke Teamlead Storage & Networking hare@xxxxxxx +49 911 74053 688 SUSE Software Solutions Germany GmbH, Maxfeldstr. 5, 90409 Nürnberg HRB 36809 (AG Nürnberg), GF: Felix Imendörffer