Re: [PATCH v2 09/10] qla2xxx: Add encryption to IO path

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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.
> 
> After the completion of PLOGI, both sides have authenticated
> and PRLI completion, encrypted IOs are allow to proceed. This patch
> adds the follow:
> - use new FW api to encrypt traffic on the wire.
> - add driver parameter to enable|disable EDIF feature.
> 
> modprobe qla2xxx ql2xsecenable=1
> 
> 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_edif.c   | 341 ++++++++++++++++++++++++++----
>  drivers/scsi/qla2xxx/qla_fw.h     |   3 +
>  drivers/scsi/qla2xxx/qla_gbl.h    |   4 +
>  drivers/scsi/qla2xxx/qla_gs.c     |   2 +-
>  drivers/scsi/qla2xxx/qla_init.c   |  25 +--
>  drivers/scsi/qla2xxx/qla_iocb.c   |   5 +-
>  drivers/scsi/qla2xxx/qla_mbx.c    |  28 ++-
>  drivers/scsi/qla2xxx/qla_nvme.c   |   4 +
>  drivers/scsi/qla2xxx/qla_os.c     |   9 +-
>  drivers/scsi/qla2xxx/qla_target.c |  41 +++-
>  drivers/scsi/qla2xxx/qla_target.h |  16 +-
>  11 files changed, 407 insertions(+), 71 deletions(-)
> 
> diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c
> index 721898afb064..9f66ac6d1c77 100644
> --- a/drivers/scsi/qla2xxx/qla_edif.c
> +++ b/drivers/scsi/qla2xxx/qla_edif.c
> @@ -556,41 +556,30 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
>  	}
>  
>  	list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) {
> -		if ((fcport->flags & FCF_FCSP_DEVICE)) {
> -			ql_dbg(ql_dbg_edif, vha, 0xf084,
> -			    "%s: sess %p %8phC lid %#04x s_id %06x logout %d\n",
> -			    __func__, fcport, fcport->port_name,
> -			    fcport->loop_id, fcport->d_id.b24,
> -			    fcport->logout_on_delete);
> -
> -			ql_dbg(ql_dbg_edif, vha, 0xf084,
> -			    "keep %d els_logo %d disc state %d auth state %d stop state %d\n",
> -			    fcport->keep_nport_handle,
> -			    fcport->send_els_logo, fcport->disc_state,
> -			    fcport->edif.auth_state, fcport->edif.app_stop);
> -
> -			if (atomic_read(&vha->loop_state) == LOOP_DOWN)
> -				break;
> +		ql_dbg(ql_dbg_edif, vha, 0xf084,
> +		    "%s: sess %p %8phC lid %#04x s_id %06x logout %d\n",
> +		    __func__, fcport, fcport->port_name,
> +		    fcport->loop_id, fcport->d_id.b24,
> +		    fcport->logout_on_delete);
> +
> +		ql_dbg(ql_dbg_edif, vha, 0xf084,
> +		    "keep %d els_logo %d disc state %d auth state %d stop state %d\n",
> +		    fcport->keep_nport_handle,
> +		    fcport->send_els_logo, fcport->disc_state,
> +		    fcport->edif.auth_state, fcport->edif.app_stop);
> +
> +		if (atomic_read(&vha->loop_state) == LOOP_DOWN)
> +			break;
>  
> -			if (!fcport->edif.secured_login)
> -				continue;
> +		fcport->edif.app_started = 1;
> +		fcport->edif.app_stop = 0;
>  
> -			fcport->edif.app_started = 1;
> -			if (fcport->edif.app_stop ||
> -			    (fcport->disc_state != DSC_LOGIN_COMPLETE &&
> -			     fcport->disc_state != DSC_LOGIN_PEND &&
> -			     fcport->disc_state != DSC_DELETED)) {
> -				/* no activity */
> -				fcport->edif.app_stop = 0;
> -
> -				ql_dbg(ql_dbg_edif, vha, 0x911e,
> -				    "%s wwpn %8phC calling qla_edif_reset_auth_wait\n",
> -				    __func__, fcport->port_name);
> -				fcport->edif.app_sess_online = 1;
> -				qla_edif_reset_auth_wait(fcport, DSC_LOGIN_PEND, 0);
> -			}
> -			qla_edif_sa_ctl_init(vha, fcport);
> -		}
> +		ql_dbg(ql_dbg_edif, vha, 0x911e,
> +		    "%s wwpn %8phC calling qla_edif_reset_auth_wait\n",
> +		    __func__, fcport->port_name);
> +		fcport->edif.app_sess_online = 1;
> +		qla_edif_reset_auth_wait(fcport, DSC_LOGIN_PEND, 0);
> +		qla_edif_sa_ctl_init(vha, fcport);
>  	}
>  
>  	if (vha->pur_cinfo.enode_flags != ENODE_ACTIVE) {
> @@ -720,10 +709,7 @@ qla_edif_app_authok(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
>  	struct fc_bsg_reply	*bsg_reply = bsg_job->reply;
>  	fc_port_t		*fcport = NULL;
>  	port_id_t		portid = {0};
> -	/* port_id_t		portid = {0x10100}; */
> -	/* int i; */
>  
> -	/* ql_dbg(ql_dbg_edif, vha, 0x911d, "%s app auth ok\n", __func__); */
>  
>  	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
>  	    bsg_job->request_payload.sg_cnt, &appplogiok,
> @@ -938,6 +924,9 @@ qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
>  			if (tdid.b24 != 0 && tdid.b24 != fcport->d_id.b24)
>  				continue;
>  
> +			app_reply->ports[pcnt].rekey_count =
> +				fcport->edif.rekey_cnt;
> +
>  			app_reply->ports[pcnt].remote_type =
>  				VND_CMD_RTYPE_UNKNOWN;
>  			if (fcport->port_type & (FCT_NVME_TARGET | FCT_TARGET))
> @@ -1089,8 +1078,8 @@ qla_edif_app_mgmt(struct bsg_job *bsg_job)
>  	if (!vha->hw->flags.edif_enabled ||
>  		test_bit(VPORT_DELETE, &vha->dpc_flags)) {
>  		ql_dbg(ql_dbg_edif, vha, 0x911d,
> -		    "%s edif not enabled or vp delete. bsg ptr done %p\n",
> -		    __func__, bsg_job);
> +		    "%s edif not enabled or vp delete. bsg ptr done %p. dpc_flags %lx\n",
> +		    __func__, bsg_job, vha->dpc_flags);
>  
>  		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
>  		goto done;
> @@ -2270,16 +2259,10 @@ void qla24xx_sa_update_iocb(srb_t *sp, struct sa_update_28xx *sa_update_iocb)
>  		sa_update_iocb->sa_control |= SA_CNTL_KEY256;
>  		for (itr = 0; itr < 32; itr++)
>  			sa_update_iocb->sa_key[itr] = sa_frame->sa_key[itr];
> -
> -		ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x921f, "%s 256 sa key=%32phN\n",
> -		    __func__, sa_update_iocb->sa_key);
>  	} else {
>  		sa_update_iocb->sa_control |= SA_CNTL_KEY128;
>  		for (itr = 0; itr < 16; itr++)
>  			sa_update_iocb->sa_key[itr] = sa_frame->sa_key[itr];
> -
> -		ql_dbg(ql_dbg_edif +  ql_dbg_verbose, vha, 0x921f, "%s 128 sa key=%16phN\n",
> -		    __func__, sa_update_iocb->sa_key);
>  	}
>  
>  	ql_dbg(ql_dbg_edif, vha, 0x921d,
> @@ -2745,6 +2728,276 @@ qla28xx_sa_update_iocb_entry(scsi_qla_host_t *v, struct req_que *req,
>  	sp->done(sp, 0);
>  }
>  
> +/*
> + * qla28xx_start_scsi_edif() - Send a SCSI type 6 command ot the ISP
> + * @sp: command to send to the ISP
> + * req/rsp queue to use for this request
> + * lock to protect submission
> + *
> + * Returns non-zero if a failure occurred, else zero.
> + */
> +int
> +qla28xx_start_scsi_edif(srb_t *sp)
> +{
> +	int             nseg;
> +	unsigned long   flags;
> +	struct scsi_cmnd *cmd;
> +	uint32_t        *clr_ptr;
> +	uint32_t        index, i;
> +	uint32_t        handle;
> +	uint16_t        cnt;
> +	int16_t        req_cnt;
> +	uint16_t        tot_dsds;
> +	__be32 *fcp_dl;
> +	uint8_t additional_cdb_len;
> +	struct ct6_dsd *ctx;
> +	struct scsi_qla_host *vha = sp->vha;
> +	struct qla_hw_data *ha = vha->hw;
> +	struct cmd_type_6 *cmd_pkt;
> +	struct dsd64	*cur_dsd;
> +	uint8_t		avail_dsds = 0;
> +	struct scatterlist *sg;
> +	struct req_que *req = sp->qpair->req;
> +	spinlock_t *lock = sp->qpair->qp_lock_ptr;
> +
> +	/* Setup device pointers. */
> +	cmd = GET_CMD_SP(sp);
> +
> +	/* So we know we haven't pci_map'ed anything yet */
> +	tot_dsds = 0;
> +
> +	/* Send marker if required */
> +	if (vha->marker_needed != 0) {
> +		if (qla2x00_marker(vha, sp->qpair, 0, 0, MK_SYNC_ALL) !=
> +			QLA_SUCCESS) {
> +			ql_log(ql_log_warn, vha, 0x300c,
> +			    "qla2x00_marker failed for cmd=%p.\n", cmd);
> +			return QLA_FUNCTION_FAILED;
> +		}
> +		vha->marker_needed = 0;
> +	}
> +
> +	/* Acquire ring specific lock */
> +	spin_lock_irqsave(lock, flags);
> +
> +	/* Check for room in outstanding command list. */
> +	handle = req->current_outstanding_cmd;
> +	for (index = 1; index < req->num_outstanding_cmds; index++) {
> +		handle++;
> +		if (handle == req->num_outstanding_cmds)
> +			handle = 1;
> +		if (!req->outstanding_cmds[handle])
> +			break;
> +	}
> +	if (index == req->num_outstanding_cmds)
> +		goto queuing_error;
> +
> +	/* Map the sg table so we have an accurate count of sg entries needed */
> +	if (scsi_sg_count(cmd)) {
> +		nseg = dma_map_sg(&ha->pdev->dev, scsi_sglist(cmd),
> +		    scsi_sg_count(cmd), cmd->sc_data_direction);
> +		if (unlikely(!nseg))
> +			goto queuing_error;
> +	} else {
> +		nseg = 0;
> +	}
> +
> +	tot_dsds = nseg;
> +	req_cnt = qla24xx_calc_iocbs(vha, tot_dsds);
> +	if (req->cnt < (req_cnt + 2)) {
> +		cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr :
> +		    rd_reg_dword(req->req_q_out);
> +		if (req->ring_index < cnt)
> +			req->cnt = cnt - req->ring_index;
> +		else
> +			req->cnt = req->length -
> +			    (req->ring_index - cnt);
> +		if (req->cnt < (req_cnt + 2))
> +			goto queuing_error;
> +	}
> +
> +	ctx = sp->u.scmd.ct6_ctx =
> +	    mempool_alloc(ha->ctx_mempool, GFP_ATOMIC);
> +	if (!ctx) {
> +		ql_log(ql_log_fatal, vha, 0x3010,
> +		    "Failed to allocate ctx for cmd=%p.\n", cmd);
> +		goto queuing_error;
> +	}
> +
> +	memset(ctx, 0, sizeof(struct ct6_dsd));
> +	ctx->fcp_cmnd = dma_pool_zalloc(ha->fcp_cmnd_dma_pool,
> +	    GFP_ATOMIC, &ctx->fcp_cmnd_dma);
> +	if (!ctx->fcp_cmnd) {
> +		ql_log(ql_log_fatal, vha, 0x3011,
> +		    "Failed to allocate fcp_cmnd for cmd=%p.\n", cmd);
> +		goto queuing_error;
> +	}
> +
> +	/* Initialize the DSD list and dma handle */
> +	INIT_LIST_HEAD(&ctx->dsd_list);
> +	ctx->dsd_use_cnt = 0;
> +
> +	if (cmd->cmd_len > 16) {
> +		additional_cdb_len = cmd->cmd_len - 16;
> +		if ((cmd->cmd_len % 4) != 0) {
> +			/*
> +			 * SCSI command bigger than 16 bytes must be
> +			 * multiple of 4
> +			 */
> +			ql_log(ql_log_warn, vha, 0x3012,
> +			    "scsi cmd len %d not multiple of 4 for cmd=%p.\n",
> +			    cmd->cmd_len, cmd);
> +			goto queuing_error_fcp_cmnd;
> +		}
> +		ctx->fcp_cmnd_len = 12 + cmd->cmd_len + 4;
> +	} else {
> +		additional_cdb_len = 0;
> +		ctx->fcp_cmnd_len = 12 + 16 + 4;
> +	}
> +
> +	cmd_pkt = (struct cmd_type_6 *)req->ring_ptr;
> +	cmd_pkt->handle = make_handle(req->id, handle);
> +
> +	/*
> +	 * Zero out remaining portion of packet.
> +	 * tagged queuing modifier -- default is TSK_SIMPLE (0).
> +	 */
> +	clr_ptr = (uint32_t *)cmd_pkt + 2;
> +	memset(clr_ptr, 0, REQUEST_ENTRY_SIZE - 8);
> +	cmd_pkt->dseg_count = cpu_to_le16(tot_dsds);
> +
> +	/* No data transfer */
> +	if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) {
> +		cmd_pkt->byte_count = cpu_to_le32(0);
> +		goto no_dsds;
> +	}
> +
> +	/* Set transfer direction */
> +	if (cmd->sc_data_direction == DMA_TO_DEVICE) {
> +		cmd_pkt->control_flags = cpu_to_le16(CF_WRITE_DATA);
> +		vha->qla_stats.output_bytes += scsi_bufflen(cmd);
> +		vha->qla_stats.output_requests++;
> +		sp->fcport->edif.tx_bytes += scsi_bufflen(cmd);
> +	} else if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
> +		cmd_pkt->control_flags = cpu_to_le16(CF_READ_DATA);
> +		vha->qla_stats.input_bytes += scsi_bufflen(cmd);
> +		vha->qla_stats.input_requests++;
> +		sp->fcport->edif.rx_bytes += scsi_bufflen(cmd);
> +	}
> +
> +	cmd_pkt->control_flags |= cpu_to_le16(CF_EN_EDIF);
> +	cmd_pkt->control_flags &= ~(cpu_to_le16(CF_NEW_SA));
> +
> +	/* One DSD is available in the Command Type 6 IOCB */
> +	avail_dsds = 1;
> +	cur_dsd = &cmd_pkt->fcp_dsd;
> +
> +	/* Load data segments */
> +	scsi_for_each_sg(cmd, sg, tot_dsds, i) {
> +		dma_addr_t      sle_dma;
> +		cont_a64_entry_t *cont_pkt;
> +
> +		/* Allocate additional continuation packets? */
> +		if (avail_dsds == 0) {
> +			/*
> +			 * Five DSDs are available in the Continuation
> +			 * Type 1 IOCB.
> +			 */
> +			cont_pkt = qla2x00_prep_cont_type1_iocb(vha, req);
> +			cur_dsd = cont_pkt->dsd;
> +			avail_dsds = 5;
> +		}
> +
> +		sle_dma = sg_dma_address(sg);
> +		put_unaligned_le64(sle_dma, &cur_dsd->address);
> +		cur_dsd->length = cpu_to_le32(sg_dma_len(sg));
> +		cur_dsd++;
> +		avail_dsds--;
> +	}
> +
> +no_dsds:
> +	/* Set NPORT-ID and LUN number*/
> +	cmd_pkt->nport_handle = cpu_to_le16(sp->fcport->loop_id);
> +	cmd_pkt->port_id[0] = sp->fcport->d_id.b.al_pa;
> +	cmd_pkt->port_id[1] = sp->fcport->d_id.b.area;
> +	cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain;
> +	cmd_pkt->vp_index = sp->vha->vp_idx;
> +
> +	cmd_pkt->entry_type = COMMAND_TYPE_6;
> +
> +	/* Set total data segment count. */
> +	cmd_pkt->entry_count = (uint8_t)req_cnt;
> +
> +	int_to_scsilun(cmd->device->lun, &cmd_pkt->lun);
> +	host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun));
> +
> +	/* build FCP_CMND IU */
> +	int_to_scsilun(cmd->device->lun, &ctx->fcp_cmnd->lun);
> +	ctx->fcp_cmnd->additional_cdb_len = additional_cdb_len;
> +
> +	if (cmd->sc_data_direction == DMA_TO_DEVICE)
> +		ctx->fcp_cmnd->additional_cdb_len |= 1;
> +	else if (cmd->sc_data_direction == DMA_FROM_DEVICE)
> +		ctx->fcp_cmnd->additional_cdb_len |= 2;
> +
> +	/* Populate the FCP_PRIO. */
> +	if (ha->flags.fcp_prio_enabled)
> +		ctx->fcp_cmnd->task_attribute |=
> +		    sp->fcport->fcp_prio << 3;
> +
> +	memcpy(ctx->fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len);
> +
> +	fcp_dl = (__be32 *)(ctx->fcp_cmnd->cdb + 16 +
> +	    additional_cdb_len);
> +	*fcp_dl = htonl((uint32_t)scsi_bufflen(cmd));
> +
> +	cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(ctx->fcp_cmnd_len);
> +	put_unaligned_le64(ctx->fcp_cmnd_dma, &cmd_pkt->fcp_cmnd_dseg_address);
> +
> +	sp->flags |= SRB_FCP_CMND_DMA_VALID;
> +	cmd_pkt->byte_count = cpu_to_le32((uint32_t)scsi_bufflen(cmd));
> +	/* Set total data segment count. */
> +	cmd_pkt->entry_count = (uint8_t)req_cnt;
> +	cmd_pkt->entry_status = 0;
> +
> +	/* Build command packet. */
> +	req->current_outstanding_cmd = handle;
> +	req->outstanding_cmds[handle] = sp;
> +	sp->handle = handle;
> +	cmd->host_scribble = (unsigned char *)(unsigned long)handle;
> +	req->cnt -= req_cnt;
> +
> +	/* Adjust ring index. */
> +	wmb();
> +	req->ring_index++;
> +	if (req->ring_index == req->length) {
> +		req->ring_index = 0;
> +		req->ring_ptr = req->ring;
> +	} else {
> +		req->ring_ptr++;
> +	}
> +
> +	/* Set chip new ring index. */
> +	wrt_reg_dword(req->req_q_in, req->ring_index);
> +
> +	spin_unlock_irqrestore(lock, flags);
> +	return QLA_SUCCESS;
> +
> +queuing_error_fcp_cmnd:
> +	dma_pool_free(ha->fcp_cmnd_dma_pool, ctx->fcp_cmnd, ctx->fcp_cmnd_dma);
> +queuing_error:
> +	if (tot_dsds)
> +		scsi_dma_unmap(cmd);
> +
> +	if (sp->u.scmd.ct6_ctx) {
> +		mempool_free(sp->u.scmd.ct6_ctx, ha->ctx_mempool);
> +		sp->u.scmd.ct6_ctx = NULL;
> +	}
> +	spin_unlock_irqrestore(lock, flags);
> +
> +	return QLA_FUNCTION_FAILED;
> +}
> +
>  /**********************************************
>   * edif update/delete sa_index list functions *
>   **********************************************/
> diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h
> index 4934b08a8990..c257af8d87fd 100644
> --- a/drivers/scsi/qla2xxx/qla_fw.h
> +++ b/drivers/scsi/qla2xxx/qla_fw.h
> @@ -490,6 +490,9 @@ struct cmd_type_6 {
>  	struct scsi_lun lun;		/* FCP LUN (BE). */
>  
>  	__le16	control_flags;		/* Control flags. */
> +#define CF_NEW_SA			BIT_12
> +#define CF_EN_EDIF			BIT_9
> +#define CF_ADDITIONAL_PARAM_BLK		BIT_8
>  #define CF_DIF_SEG_DESCR_ENABLE		BIT_3
>  #define CF_DATA_SEG_DESCR_ENABLE	BIT_2
>  #define CF_READ_DATA			BIT_1
> diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
> index cc78339b47ac..be94b335f211 100644
> --- a/drivers/scsi/qla2xxx/qla_gbl.h
> +++ b/drivers/scsi/qla2xxx/qla_gbl.h
> @@ -189,6 +189,7 @@ extern int qla2xuseresexchforels;
>  extern int ql2xexlogins;
>  extern int ql2xdifbundlinginternalbuffers;
>  extern int ql2xfulldump_on_mpifail;
> +extern int ql2xsecenable;
>  extern int ql2xenforce_iocb_limit;
>  extern int ql2xabts_wait_nvme;
>  
> @@ -299,6 +300,8 @@ extern int  qla2x00_vp_abort_isp(scsi_qla_host_t *);
>   */
>  void qla_els_pt_iocb(struct scsi_qla_host *vha,
>  	struct els_entry_24xx *pkt, struct qla_els_pt_arg *a);
> +cont_a64_entry_t *qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *vha,
> +		struct req_que *que);
>  extern uint16_t qla2x00_calc_iocbs_32(uint16_t);
>  extern uint16_t qla2x00_calc_iocbs_64(uint16_t);
>  extern void qla2x00_build_scsi_iocbs_32(srb_t *, cmd_entry_t *, uint16_t);
> @@ -990,6 +993,7 @@ void qla_enode_init(scsi_qla_host_t *vha);
>  void qla_enode_stop(scsi_qla_host_t *vha);
>  void qla_edif_flush_sa_ctl_lists(fc_port_t *fcport);
>  void qla_edb_init(scsi_qla_host_t *vha);
> +int qla28xx_start_scsi_edif(srb_t *sp);
>  void qla24xx_sa_update_iocb(srb_t *sp, struct sa_update_28xx *sa_update_iocb);
>  void qla24xx_sa_replace_iocb(srb_t *sp, struct sa_update_28xx *sa_update_iocb);
>  void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp);
> diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
> index 99fb330053ae..b16b7d16be12 100644
> --- a/drivers/scsi/qla2xxx/qla_gs.c
> +++ b/drivers/scsi/qla2xxx/qla_gs.c
> @@ -632,7 +632,7 @@ static int qla_async_rftid(scsi_qla_host_t *vha, port_id_t *d_id)
>  	ct_req->req.rft_id.port_id = port_id_to_be_id(vha->d_id);
>  	ct_req->req.rft_id.fc4_types[2] = 0x01;		/* FCP-3 */
>  
> -	if (vha->flags.nvme_enabled)
> +	if (vha->flags.nvme_enabled && qla_ini_mode_enabled(vha))
>  		ct_req->req.rft_id.fc4_types[6] = 1;    /* NVMe type 28h */
>  
>  	sp->u.iocb_cmd.u.ctarg.req_size = RFT_ID_REQ_SIZE;
> diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
> index bef9bf59bc50..f6ea51143651 100644
> --- a/drivers/scsi/qla2xxx/qla_init.c
> +++ b/drivers/scsi/qla2xxx/qla_init.c
> @@ -345,16 +345,15 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport,
>  	if (N2N_TOPO(fcport->vha->hw) && fcport_is_bigger(fcport)) {
>  		lio->u.logio.flags |= SRB_LOGIN_PRLI_ONLY;
>  	} else {
> -		if (vha->hw->flags.edif_enabled) {
> -			if (fcport->edif.non_secured_login == 0) {
> -				lio->u.logio.flags |=
> -					(SRB_LOGIN_FCSP | SRB_LOGIN_SKIP_PRLI);
> -				ql_dbg(ql_dbg_disc, vha, 0x2072,
> +		if (vha->hw->flags.edif_enabled &&
> +		    vha->e_dbell.db_flags & EDB_ACTIVE) {
> +			lio->u.logio.flags |=
> +				(SRB_LOGIN_FCSP | SRB_LOGIN_SKIP_PRLI);
> +			ql_dbg(ql_dbg_disc, vha, 0x2072,
>  	"Async-login: w/ FCSP %8phC hdl=%x, loopid=%x portid=%06x\n",
> -				    fcport->port_name, sp->handle,
> -				    fcport->loop_id,
> -				    fcport->d_id.b24);
> -			}
> +			       fcport->port_name, sp->handle,
> +			       fcport->loop_id,
> +			       fcport->d_id.b24);
>  		} else {
>  			lio->u.logio.flags |= SRB_LOGIN_COND_PLOGI;
>  		}
> @@ -3965,7 +3964,8 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
>  		}
>  
>  		/* Enable PUREX PASSTHRU */
> -		if (ql2xrdpenable || ha->flags.scm_supported_f)
> +		if (ql2xrdpenable || ha->flags.scm_supported_f ||
> +		    ha->flags.edif_enabled)
>  			qla25xx_set_els_cmds_supported(vha);
>  	} else
>  		goto failed;
> @@ -4150,7 +4150,7 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha)
>  	}
>  
>  	/* Move PUREX, ABTS RX & RIDA to ATIOQ */
> -	if (ql2xmvasynctoatio &&
> +	if (ql2xmvasynctoatio && !ha->flags.edif_enabled &&
>  	    (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha))) {
>  		if (qla_tgt_mode_enabled(vha) ||
>  		    qla_dual_mode_enabled(vha))
> @@ -4178,7 +4178,8 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha)
>  			ha->fw_options[2] &= ~BIT_8;
>  	}
>  
> -	if (ql2xrdpenable || ha->flags.scm_supported_f)
> +	if (ql2xrdpenable || ha->flags.scm_supported_f ||
> +	    ha->flags.edif_enabled)
>  		ha->fw_options[1] |= ADD_FO1_ENABLE_PUREX_IOCB;
>  
>  	/* Enable Async 8130/8131 events -- transceiver insertion/removal */
> diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
> index ba36084d17a9..67c28a2baeee 100644
> --- a/drivers/scsi/qla2xxx/qla_iocb.c
> +++ b/drivers/scsi/qla2xxx/qla_iocb.c
> @@ -118,7 +118,7 @@ qla2x00_prep_cont_type0_iocb(struct scsi_qla_host *vha)
>   *
>   * Returns a pointer to the continuation type 1 IOCB packet.
>   */
> -static inline cont_a64_entry_t *
> +cont_a64_entry_t *
>  qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *vha, struct req_que *req)
>  {
>  	cont_a64_entry_t *cont_pkt;
> @@ -1961,6 +1961,9 @@ qla2xxx_start_scsi_mq(srb_t *sp)
>  	struct qla_hw_data *ha = vha->hw;
>  	struct qla_qpair *qpair = sp->qpair;
>  
> +	if (sp->fcport->edif.enable)
> +		return qla28xx_start_scsi_edif(sp);
> +
>  	/* Acquire qpair specific lock */
>  	spin_lock_irqsave(&qpair->qp_lock, flags);
>  
> diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
> index f4b9fa9d8078..f8a060862512 100644
> --- a/drivers/scsi/qla2xxx/qla_mbx.c
> +++ b/drivers/scsi/qla2xxx/qla_mbx.c
> @@ -61,6 +61,7 @@ static struct rom_cmd {
>  	{ MBC_SET_RNID_PARAMS },
>  	{ MBC_GET_RNID_PARAMS },
>  	{ MBC_GET_SET_ZIO_THRESHOLD },
> +	{ MBC_GET_RNID_PARAMS },
>  };
>  
>  static int is_rom_cmd(uint16_t cmd)
> @@ -739,7 +740,7 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
>  			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;

Please keep the spacing.

>  	} else {
>  		mcp->mb[1] = LSW(risc_addr);
>  		mcp->out_mb |= MBX_1;
> @@ -795,6 +796,12 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
>  		}
>  	}
>  
> +	if (IS_QLA28XX(ha) && (mcp->mb[5] & BIT_10) && ql2xsecenable) {
> +		ha->flags.edif_enabled = 1;
> +		ql_log(ql_log_info, vha, 0xffff,
> +		    "%s: edif is enabled\n", __func__);
> +	}
> +
>  done:
>  	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1028,
>  	    "Done %s.\n", __func__);
> @@ -4946,7 +4953,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 +4961,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 +4983,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;
> diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c
> index 0cacb667a88b..3f2585798a44 100644
> --- a/drivers/scsi/qla2xxx/qla_nvme.c
> +++ b/drivers/scsi/qla2xxx/qla_nvme.c
> @@ -463,6 +463,10 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp)
>  	} else if (fd->io_dir == 0) {
>  		cmd_pkt->control_flags = 0;
>  	}
> +
> +	if (sp->fcport->edif.enable && fd->io_dir != 0)
> +		cmd_pkt->control_flags |= cpu_to_le16(CF_EN_EDIF);
> +
>  	/* Set BIT_13 of control flags for Async event */
>  	if (vha->flags.nvme2_enabled &&
>  	    cmd->sqe.common.opcode == nvme_admin_async_event) {
> diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
> index efc21ef80142..ffc7367fc98e 100644
> --- a/drivers/scsi/qla2xxx/qla_os.c
> +++ b/drivers/scsi/qla2xxx/qla_os.c
> @@ -53,6 +53,11 @@ static struct kmem_cache *ctx_cachep;
>   */
>  uint ql_errlev = 0x8001;
>  
> +int ql2xsecenable;
> +module_param(ql2xsecenable, int, S_IRUGO);
> +MODULE_PARM_DESC(ql2xsecenable,
> +	"Enable/disable security. 0(Default) - Security disabled. 1 - Security enabled.");
> +
>  static int ql2xenableclass2;
>  module_param(ql2xenableclass2, int, S_IRUGO|S_IRUSR);
>  MODULE_PARM_DESC(ql2xenableclass2,
> @@ -4032,7 +4037,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
>  	if (!ha->srb_mempool)
>  		goto fail_free_gid_list;
>  
> -	if (IS_P3P_TYPE(ha)) {
> +	if (IS_P3P_TYPE(ha) || IS_QLA27XX(ha) || (ql2xsecenable && IS_QLA28XX(ha))) {
>  		/* Allocate cache for CT6 Ctx. */
>  		if (!ctx_cachep) {
>  			ctx_cachep = kmem_cache_create("qla2xxx_ctx",
> @@ -4066,7 +4071,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
>  	    "init_cb=%p gid_list=%p, srb_mempool=%p s_dma_pool=%p.\n",
>  	    ha->init_cb, ha->gid_list, ha->srb_mempool, ha->s_dma_pool);
>  
> -	if (IS_P3P_TYPE(ha) || ql2xenabledif) {
> +	if (IS_P3P_TYPE(ha) || ql2xenabledif || (IS_QLA28XX(ha) && ql2xsecenable)) {
>  		ha->dl_dma_pool = dma_pool_create(name, &ha->pdev->dev,
>  			DSD_LIST_DMA_POOL_SIZE, 8, 0);
>  		if (!ha->dl_dma_pool) {
> diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
> index 5d9fafa0c5d9..6a89ea47d90e 100644
> --- a/drivers/scsi/qla2xxx/qla_target.c
> +++ b/drivers/scsi/qla2xxx/qla_target.c
> @@ -1313,8 +1313,8 @@ void qlt_schedule_sess_for_deletion(struct fc_port *sess)
>  	qla24xx_chk_fcp_state(sess);
>  
>  	ql_dbg(ql_log_warn, sess->vha, 0xe001,
> -	    "Scheduling sess %p for deletion %8phC\n",
> -	    sess, sess->port_name);
> +	    "Scheduling sess %p for deletion %8phC fc4_type %x\n",
> +	    sess, sess->port_name, sess->fc4_type);
>  
>  	WARN_ON(!queue_work(sess->vha->hw->wq, &sess->del_work));
>  }
> @@ -2610,6 +2610,7 @@ static int qlt_24xx_build_ctio_pkt(struct qla_qpair *qpair,
>  	struct ctio7_to_24xx *pkt;
>  	struct atio_from_isp *atio = &prm->cmd->atio;
>  	uint16_t temp;
> +	struct qla_tgt_cmd      *cmd = prm->cmd;
>  
>  	pkt = (struct ctio7_to_24xx *)qpair->req->ring_ptr;
>  	prm->pkt = pkt;
> @@ -2642,6 +2643,15 @@ static int qlt_24xx_build_ctio_pkt(struct qla_qpair *qpair,
>  	pkt->u.status0.ox_id = cpu_to_le16(temp);
>  	pkt->u.status0.relative_offset = cpu_to_le32(prm->cmd->offset);
>  
> +	if (cmd->edif) {
> +		if (cmd->dma_data_direction == DMA_TO_DEVICE)
> +			prm->cmd->sess->edif.rx_bytes += cmd->bufflen;
> +		if (cmd->dma_data_direction == DMA_FROM_DEVICE)
> +			prm->cmd->sess->edif.tx_bytes += cmd->bufflen;
> +
> +		pkt->u.status0.edif_flags |= EF_EN_EDIF;
> +	}
> +
>  	return 0;
>  }
>  
> @@ -3332,8 +3342,10 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
>  			if (xmit_type & QLA_TGT_XMIT_STATUS) {
>  				pkt->u.status0.scsi_status =
>  				    cpu_to_le16(prm.rq_result);
> -				pkt->u.status0.residual =
> -				    cpu_to_le32(prm.residual);
> +				if (!cmd->edif)
> +					pkt->u.status0.residual =
> +						cpu_to_le32(prm.residual);
> +
>  				pkt->u.status0.flags |= cpu_to_le16(
>  				    CTIO7_FLAGS_SEND_STATUS);
>  				if (qlt_need_explicit_conf(cmd, 0)) {
> @@ -3980,6 +3992,12 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha,
>  	if (cmd == NULL)
>  		return;
>  
> +	if ((le16_to_cpu(((struct ctio7_from_24xx *)ctio)->flags) & CTIO7_FLAGS_DATA_OUT) &&
> +	    cmd->sess) {
> +		qlt_chk_edif_rx_sa_delete_pending(vha, cmd->sess,
> +		    (struct ctio7_from_24xx *)ctio);
> +	}
> +
>  	se_cmd = &cmd->se_cmd;
>  	cmd->cmd_sent_to_fw = 0;
>  
> @@ -4050,6 +4068,16 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha,
>  			qlt_handle_dif_error(qpair, cmd, ctio);
>  			return;
>  		}
> +
> +		case CTIO_FAST_AUTH_ERR:
> +		case CTIO_FAST_INCOMP_PAD_LEN:
> +		case CTIO_FAST_INVALID_REQ:
> +		case CTIO_FAST_SPI_ERR:
> +			ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05b,
> +	"qla_target(%d): CTIO with EDIF error status 0x%x received (state %x, se_cmd %p\n",
> +			    vha->vp_idx, status, cmd->state, se_cmd);
> +			break;
> +
>  		default:
>  			ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05b,
>  			    "qla_target(%d): CTIO with error status 0x%x received (state %x, se_cmd %p\n",
> @@ -4351,6 +4379,7 @@ static struct qla_tgt_cmd *qlt_get_tag(scsi_qla_host_t *vha,
>  	qlt_assign_qpair(vha, cmd);
>  	cmd->reset_count = vha->hw->base_qpair->chip_reset;
>  	cmd->vp_idx = vha->vp_idx;
> +	cmd->edif = sess->edif.enable;
>  
>  	return cmd;
>  }
> @@ -4767,7 +4796,9 @@ static int qlt_handle_login(struct scsi_qla_host *vha,
>  	}
>  
>  	if (vha->hw->flags.edif_enabled &&
> -	    vha->e_dbell.db_flags != EDB_ACTIVE) {
> +	    !(vha->e_dbell.db_flags & EDB_ACTIVE) &&
> +	    iocb->u.isp24.status_subcode == ELS_PLOGI &&
> +	    !(le16_to_cpu(iocb->u.isp24.flags) & NOTIFY24XX_FLAGS_FCSP)) {
>  		ql_dbg(ql_dbg_disc, vha, 0xffff,
>  			"%s %d Term INOT due to app not available lid=%d, NportID %06X ",
>  			__func__, __LINE__, loop_id, port_id.b24);
> diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h
> index b910f8f09353..156b950ca7e7 100644
> --- a/drivers/scsi/qla2xxx/qla_target.h
> +++ b/drivers/scsi/qla2xxx/qla_target.h
> @@ -239,6 +239,10 @@ struct ctio_to_2xxx {
>  #define CTIO_PORT_LOGGED_OUT		0x29
>  #define CTIO_PORT_CONF_CHANGED		0x2A
>  #define CTIO_SRR_RECEIVED		0x45
> +#define CTIO_FAST_AUTH_ERR		0x63
> +#define CTIO_FAST_INCOMP_PAD_LEN	0x65
> +#define CTIO_FAST_INVALID_REQ		0x66
> +#define CTIO_FAST_SPI_ERR		0x67
>  #endif
>  
>  #ifndef CTIO_RET_TYPE
> @@ -409,7 +413,16 @@ struct ctio7_to_24xx {
>  		struct {
>  			__le16	reserved1;
>  			__le16 flags;
> -			__le32	residual;
> +			union {
> +				__le32	residual;
> +				struct {
> +					uint8_t rsvd1;
> +					uint8_t edif_flags;
> +#define EF_EN_EDIF	BIT_0
> +#define EF_NEW_SA	BIT_1
> +					uint16_t rsvd2;
> +				};
> +			};
>  			__le16 ox_id;
>  			__le16	scsi_status;
>  			__le32	relative_offset;
> @@ -876,6 +889,7 @@ struct qla_tgt_cmd {
>  	unsigned int term_exchg:1;
>  	unsigned int cmd_sent_to_fw:1;
>  	unsigned int cmd_in_wq:1;
> +	unsigned int edif:1;
>  
>  	/*
>  	 * This variable may be set from outside the LIO and I/O completion
> 
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)



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux