Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f83adb61 authored by Quinn Tran's avatar Quinn Tran Committed by Christoph Hellwig
Browse files

qla2xxx: T10-Dif: add T10-PI support



Add support for T10-Dif for Target Mode to qla driver.
The driver will look for firmware attribute that support
this feature.  When the feature is present, the capabilities
will be report to TCM layer.

Add CTIO CRC2 iocb to build T10-Dif commands.
Add support routines to process good & error cases.

Signed-off-by: default avatarQuinn Tran <quinn.tran@qlogic.com>
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
Signed-off-by: default avatarGiridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: default avatarSaurav Kashyap <saurav.kashyap@qlogic.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent 5921cda6
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -66,7 +66,7 @@
 * |                              |                    | 0xd030-0xd0ff	|
 * |                              |                    | 0xd101-0xd1fe	|
 * |                              |                    | 0xd213-0xd2fe	|
 * | Target Mode		  |	  0xe070       | 0xe021		|
 * | Target Mode		  |	  0xe078       |		|
 * | Target Mode Management	  |	  0xf072       | 0xf002-0xf003	|
 * |                              |                    | 0xf046-0xf049  |
 * | Target Mode Task Management  |	  0x1000b      |		|
+12 −2
Original line number Diff line number Diff line
@@ -1629,10 +1629,20 @@ typedef struct {
#define PO_MODE_DIF_PASS	2
#define PO_MODE_DIF_REPLACE	3
#define PO_MODE_DIF_TCP_CKSUM	6
#define PO_ENABLE_DIF_BUNDLING	BIT_8
#define PO_ENABLE_INCR_GUARD_SEED	BIT_3
#define PO_DISABLE_INCR_REF_TAG	BIT_5
#define PO_DISABLE_GUARD_CHECK	BIT_4
#define PO_DISABLE_INCR_REF_TAG	BIT_5
#define PO_DIS_HEADER_MODE	BIT_7
#define PO_ENABLE_DIF_BUNDLING	BIT_8
#define PO_DIS_FRAME_MODE	BIT_9
#define PO_DIS_VALD_APP_ESC	BIT_10 /* Dis validation for escape tag/ffffh */
#define PO_DIS_VALD_APP_REF_ESC BIT_11

#define PO_DIS_APP_TAG_REPL	BIT_12 /* disable REG Tag replacement */
#define PO_DIS_REF_TAG_REPL	BIT_13
#define PO_DIS_APP_TAG_VALD	BIT_14 /* disable REF Tag validation */
#define PO_DIS_REF_TAG_VALD	BIT_15

/*
 * ISP queue - 64-Bit addressing, continuation crc entry structure definition.
 */
+7 −0
Original line number Diff line number Diff line
@@ -220,6 +220,13 @@ extern unsigned long qla2x00_get_async_timeout(struct scsi_qla_host *);

extern void *qla2x00_alloc_iocbs(scsi_qla_host_t *, srb_t *);
extern int qla2x00_issue_marker(scsi_qla_host_t *, int);
extern int qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *, srb_t *,
	uint32_t *, uint16_t, struct qla_tgt_cmd *);
extern int qla24xx_walk_and_build_sglist(struct qla_hw_data *, srb_t *,
	uint32_t *, uint16_t, struct qla_tgt_cmd *);
extern int qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *, srb_t *,
	uint32_t *, uint16_t, struct qla_tgt_cmd *);


/*
 * Global Function Prototypes in qla_mbx.c source file.
+11 −2
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
 * See LICENSE.qla2xxx for copyright and licensing details.
 */

#include "qla_target.h"
/**
 * qla24xx_calc_iocbs() - Determine number of Command Type 3 and
 * Continuation Type 1 IOCBs to allocate.
@@ -128,12 +129,20 @@ qla2x00_clear_loop_id(fc_port_t *fcport) {
}

static inline void
qla2x00_clean_dsd_pool(struct qla_hw_data *ha, srb_t *sp)
qla2x00_clean_dsd_pool(struct qla_hw_data *ha, srb_t *sp,
	struct qla_tgt_cmd *tc)
{
	struct dsd_dma *dsd_ptr, *tdsd_ptr;
	struct crc_context *ctx;

	if (sp)
		ctx = (struct crc_context *)GET_CMD_CTX_SP(sp);
	else if (tc)
		ctx = (struct crc_context *)tc->ctx;
	else {
		BUG();
		return;
	}

	/* clean up allocated prev pool */
	list_for_each_entry_safe(dsd_ptr, tdsd_ptr,
+99 −35
Original line number Diff line number Diff line
@@ -936,9 +936,9 @@ qla24xx_get_one_block_sg(uint32_t blk_sz, struct qla2_sgx *sgx,
	return 1;
}

static int
int
qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp,
	uint32_t *dsd, uint16_t tot_dsds)
	uint32_t *dsd, uint16_t tot_dsds, struct qla_tgt_cmd *tc)
{
	void *next_dsd;
	uint8_t avail_dsds = 0;
@@ -948,21 +948,35 @@ qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp,
	uint32_t *cur_dsd = dsd;
	uint16_t	used_dsds = tot_dsds;

	uint32_t	prot_int;
	uint32_t	prot_int; /* protection interval */
	uint32_t	partial;
	struct qla2_sgx sgx;
	dma_addr_t	sle_dma;
	uint32_t	sle_dma_len, tot_prot_dma_len = 0;
	struct scsi_cmnd *cmd = GET_CMD_SP(sp);
	struct scsi_cmnd *cmd;
	struct scsi_qla_host *vha;

	memset(&sgx, 0, sizeof(struct qla2_sgx));
	if (sp) {
		vha = sp->fcport->vha;
		cmd = GET_CMD_SP(sp);
		prot_int = cmd->device->sector_size;

	memset(&sgx, 0, sizeof(struct qla2_sgx));
		sgx.tot_bytes = scsi_bufflen(cmd);
		sgx.cur_sg = scsi_sglist(cmd);
		sgx.sp = sp;

		sg_prot = scsi_prot_sglist(cmd);
	} else if (tc) {
		vha = tc->vha;
		prot_int      = tc->blk_sz;
		sgx.tot_bytes = tc->bufflen;
		sgx.cur_sg    = tc->sg;
		sg_prot	      = tc->prot_sg;
	} else {
		BUG();
		return 1;
	}

	while (qla24xx_get_one_block_sg(prot_int, &sgx, &partial)) {

@@ -995,10 +1009,18 @@ qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp,
				return 1;
			}

			if (sp) {
				list_add_tail(&dsd_ptr->list,
			    &((struct crc_context *)sp->u.scmd.ctx)->dsd_list);
				    &((struct crc_context *)
					    sp->u.scmd.ctx)->dsd_list);

				sp->flags |= SRB_CRC_CTX_DSD_VALID;
			} else {
				list_add_tail(&dsd_ptr->list,
				    &(tc->ctx->dsd_list));
				tc->ctx_dsd_alloced = 1;
			}


			/* add new list to cmd iocb or last list */
			*cur_dsd++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma));
@@ -1033,21 +1055,35 @@ qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp,
	return 0;
}

static int
int
qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd,
	uint16_t tot_dsds)
	uint16_t tot_dsds, struct qla_tgt_cmd *tc)
{
	void *next_dsd;
	uint8_t avail_dsds = 0;
	uint32_t dsd_list_len;
	struct dsd_dma *dsd_ptr;
	struct scatterlist *sg;
	struct scatterlist *sg, *sgl;
	uint32_t *cur_dsd = dsd;
	int	i;
	uint16_t	used_dsds = tot_dsds;
	struct scsi_cmnd *cmd = GET_CMD_SP(sp);
	struct scsi_cmnd *cmd;
	struct scsi_qla_host *vha;

	scsi_for_each_sg(cmd, sg, tot_dsds, i) {
	if (sp) {
		cmd = GET_CMD_SP(sp);
		sgl = scsi_sglist(cmd);
		vha = sp->fcport->vha;
	} else if (tc) {
		sgl = tc->sg;
		vha = tc->vha;
	} else {
		BUG();
		return 1;
	}


	for_each_sg(sgl, sg, tot_dsds, i) {
		dma_addr_t	sle_dma;

		/* Allocate additional continuation packets? */
@@ -1076,10 +1112,17 @@ qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd,
				return 1;
			}

			if (sp) {
				list_add_tail(&dsd_ptr->list,
			    &((struct crc_context *)sp->u.scmd.ctx)->dsd_list);
				    &((struct crc_context *)
					    sp->u.scmd.ctx)->dsd_list);

				sp->flags |= SRB_CRC_CTX_DSD_VALID;
			} else {
				list_add_tail(&dsd_ptr->list,
				    &(tc->ctx->dsd_list));
				tc->ctx_dsd_alloced = 1;
			}

			/* add new list to cmd iocb or last list */
			*cur_dsd++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma));
@@ -1102,23 +1145,37 @@ qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd,
	return 0;
}

static int
int
qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp,
							uint32_t *dsd,
	uint16_t tot_dsds)
	uint32_t *dsd, uint16_t tot_dsds, struct qla_tgt_cmd *tc)
{
	void *next_dsd;
	uint8_t avail_dsds = 0;
	uint32_t dsd_list_len;
	struct dsd_dma *dsd_ptr;
	struct scatterlist *sg;
	struct scatterlist *sg, *sgl;
	int	i;
	struct scsi_cmnd *cmd;
	uint32_t *cur_dsd = dsd;
	uint16_t used_dsds = tot_dsds;
	struct scsi_qla_host *vha;

	if (sp) {
		cmd = GET_CMD_SP(sp);
	scsi_for_each_prot_sg(cmd, sg, tot_dsds, i) {
		sgl = scsi_prot_sglist(cmd);
		vha = sp->fcport->vha;
	} else if (tc) {
		vha = tc->vha;
		sgl = tc->prot_sg;
	} else {
		BUG();
		return 1;
	}

	ql_dbg(ql_dbg_tgt, vha, 0xe021,
		"%s: enter\n", __func__);

	for_each_sg(sgl, sg, tot_dsds, i) {
		dma_addr_t	sle_dma;

		/* Allocate additional continuation packets? */
@@ -1147,10 +1204,17 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp,
				return 1;
			}

			if (sp) {
				list_add_tail(&dsd_ptr->list,
			    &((struct crc_context *)sp->u.scmd.ctx)->dsd_list);
				    &((struct crc_context *)
					    sp->u.scmd.ctx)->dsd_list);

				sp->flags |= SRB_CRC_CTX_DSD_VALID;
			} else {
				list_add_tail(&dsd_ptr->list,
				    &(tc->ctx->dsd_list));
				tc->ctx_dsd_alloced = 1;
			}

			/* add new list to cmd iocb or last list */
			*cur_dsd++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma));
@@ -1386,10 +1450,10 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt,

	if (!bundling && tot_prot_dsds) {
		if (qla24xx_walk_and_build_sglist_no_difb(ha, sp,
		    cur_dsd, tot_dsds))
			cur_dsd, tot_dsds, NULL))
			goto crc_queuing_error;
	} else if (qla24xx_walk_and_build_sglist(ha, sp, cur_dsd,
	    (tot_dsds - tot_prot_dsds)))
			(tot_dsds - tot_prot_dsds), NULL))
		goto crc_queuing_error;

	if (bundling && tot_prot_dsds) {
@@ -1398,7 +1462,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt,
			__constant_cpu_to_le16(CF_DIF_SEG_DESCR_ENABLE);
		cur_dsd = (uint32_t *) &crc_ctx_pkt->u.bundling.dif_address;
		if (qla24xx_walk_and_build_prot_sglist(ha, sp, cur_dsd,
		    tot_prot_dsds))
				tot_prot_dsds, NULL))
			goto crc_queuing_error;
	}
	return QLA_SUCCESS;
Loading