From: Arun Easi Date: Mon, 27 Aug 2012 07:31:59 +0000 (+0530) Subject: qla2xxx: T10 DIF - ISP83xx changes. X-Git-Tag: v2.6.39-400.9.0~399 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=a4de454ced9327dfcc4df79422f42c2f0394f71f;p=users%2Fjedix%2Flinux-maple.git qla2xxx: T10 DIF - ISP83xx changes. JIRA Key: V2632FC-136 Acked-by: Giridhar Malvali Signed-off-by: Saurav Kashyap --- diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 088e181494a9..d781435aa327 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -1810,7 +1810,7 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable) if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) { if (ha->fw_attributes & BIT_4) { - int prot = 0; + int prot = 0, guard; vha->flags.difdix_supported = 1; ql_dbg(ql_dbg_user, vha, 0x7082, "Registered for DIF/DIX type 1 and 3 protection.\n"); @@ -1823,7 +1823,14 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable) | SHOST_DIX_TYPE1_PROTECTION | SHOST_DIX_TYPE2_PROTECTION | SHOST_DIX_TYPE3_PROTECTION); - scsi_host_set_guard(vha->host, SHOST_DIX_GUARD_CRC); + + guard = SHOST_DIX_GUARD_CRC; + + if (IS_PI_IPGUARD_CAPABLE(ha) && + (ql2xenabledif > 1 || IS_PI_DIFB_DIX0_CAPABLE(ha))) + guard |= SHOST_DIX_GUARD_IP; + + scsi_host_set_guard(vha->host, guard); } else vha->flags.difdix_supported = 0; } diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index c65e1ffafff5..417af0f24147 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c @@ -14,17 +14,19 @@ * | Module Init and Probe | 0x0122 | 0x4b,0xba,0xfa | * | Mailbox commands | 0x114d | 0x111a-0x111b | * | Device Discovery | 0x2087 | 0x2020-0x2022, | - * | | | 0x2016 | - * | Queue Command and IO tracing | 0x3030 | 0x3006,0x3008 | + * | | | 0x2016,0x207d | + * | Queue Command and IO tracing | 0x3030 | 0x3006,0x300b | + * | | | 0x3027-0x302a | * | | | 0x302d,0x302e | * | DPC Thread | 0x401d | 0x4002,0x4013 | * | Async Events | 0x5071 | 0x502b-0x502f | * | | | 0x5047,0x5052 | * | Timer Routines | 0x6011 | | * | User Space Interactions | 0x70c3 | 0x7018,0x702e | + * | | | 0x7020,0x7024 | * | | | 0x7039,0x7045 | * | | | 0x7073-0x7075 | - * | | | 0x708c, | + * | | | 0x708c | * | | | 0x70a5-0x70a6 | * | | | 0x70a8,0x70ab | * | | | 0x70ad-0x70ae | diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index c07119c398cb..2cde41ce591b 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -1449,9 +1449,10 @@ typedef struct { } cont_a64_entry_t; #define PO_MODE_DIF_INSERT 0 -#define PO_MODE_DIF_REMOVE BIT_0 -#define PO_MODE_DIF_PASS BIT_1 -#define PO_MODE_DIF_REPLACE (BIT_0 + BIT_1) +#define PO_MODE_DIF_REMOVE 1 +#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 @@ -2726,6 +2727,12 @@ struct qla_hw_data { /* Bit 21 of fw_attributes decides the MCTP capabilities */ #define IS_MCTP_CAPABLE(ha) (IS_QLA2031(ha) && \ ((ha)->fw_attributes_ext[0] & BIT_0)) +#define IS_PI_UNINIT_CAPABLE(ha) (IS_QLA83XX(ha)) +#define IS_PI_IPGUARD_CAPABLE(ha) (IS_QLA83XX(ha)) +#define IS_PI_DIFB_DIX0_CAPABLE(ha) (0) +#define IS_PI_SPLIT_DET_CAPABLE_HBA(ha) (IS_QLA83XX(ha)) +#define IS_PI_SPLIT_DET_CAPABLE(ha) (IS_PI_SPLIT_DET_CAPABLE_HBA(ha) && \ + (((ha)->fw_attributes_h << 16 | (ha)->fw_attributes) & BIT_22)) /* HBA serial number */ uint8_t serial0; diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index cf68960e4786..eeeba5e9f784 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -5439,6 +5439,9 @@ qla81xx_nvram_config(scsi_qla_host_t *vha) rval = 1; } + if (IS_T10_PI_CAPABLE(ha)) + nv->frame_payload_size &= ~7; + /* Reset Initialization control block */ memset(icb, 0, ha->init_cb_size); diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index c0364166bef2..a90152a30bbb 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -146,13 +146,6 @@ qla24xx_configure_prot_mode(srb_t *sp, uint16_t *fw_prot_opts) struct scsi_cmnd *cmd = GET_CMD_SP(sp); uint8_t guard = scsi_host_get_guard(cmd->device->host); - /* We only support T10 DIF right now */ - if (guard != SHOST_DIX_GUARD_CRC) { - ql_dbg(ql_dbg_io, sp->fcport->vha, 0x3007, - "Unsupported guard: %d for cmd=%p.\n", guard, cmd); - return 0; - } - /* We always use DIFF Bundling for best performance */ *fw_prot_opts = 0; @@ -171,10 +164,11 @@ qla24xx_configure_prot_mode(srb_t *sp, uint16_t *fw_prot_opts) *fw_prot_opts |= PO_MODE_DIF_REMOVE; break; case SCSI_PROT_READ_PASS: - *fw_prot_opts |= PO_MODE_DIF_PASS; - break; case SCSI_PROT_WRITE_PASS: - *fw_prot_opts |= PO_MODE_DIF_PASS; + if (guard & SHOST_DIX_GUARD_IP) + *fw_prot_opts |= PO_MODE_DIF_TCP_CKSUM; + else + *fw_prot_opts |= PO_MODE_DIF_PASS; break; default: /* Normal Request */ *fw_prot_opts |= PO_MODE_DIF_PASS; @@ -797,7 +791,6 @@ qla24xx_set_t10dif_tags(srb_t *sp, struct fw_dif_context *pkt, unsigned int protcnt) { struct scsi_cmnd *cmd = GET_CMD_SP(sp); - scsi_qla_host_t *vha = shost_priv(cmd->device->host); switch (scsi_get_prot_type(cmd)) { case SCSI_PROT_DIF_TYPE0: @@ -867,12 +860,6 @@ qla24xx_set_t10dif_tags(srb_t *sp, struct fw_dif_context *pkt, pkt->ref_tag_mask[3] = 0xff; break; } - - ql_dbg(ql_dbg_io, vha, 0x3009, - "Setting protection Tags: (BIG) ref tag = 0x%x, app tag = 0x%x, " - "prot SG count %d, cmd lba 0x%x, prot_type=%u cmd=%p.\n", - pkt->ref_tag, pkt->app_tag, protcnt, (int)scsi_get_lba(cmd), - scsi_get_prot_type(cmd), cmd); } struct qla2_sgx { @@ -1044,9 +1031,6 @@ qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd, int i; uint16_t used_dsds = tot_dsds; struct scsi_cmnd *cmd = GET_CMD_SP(sp); - scsi_qla_host_t *vha = shost_priv(cmd->device->host); - - uint8_t *cp; scsi_for_each_sg(cmd, sg, tot_dsds, i) { dma_addr_t sle_dma; @@ -1089,19 +1073,12 @@ qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd, cur_dsd = (uint32_t *)next_dsd; } sle_dma = sg_dma_address(sg); - ql_dbg(ql_dbg_io, vha, 0x300a, - "sg entry %d - addr=0x%x 0x%x, " "len=%d for cmd=%p.\n", - i, LSD(sle_dma), MSD(sle_dma), sg_dma_len(sg), cmd); + *cur_dsd++ = cpu_to_le32(LSD(sle_dma)); *cur_dsd++ = cpu_to_le32(MSD(sle_dma)); *cur_dsd++ = cpu_to_le32(sg_dma_len(sg)); avail_dsds--; - if (scsi_get_prot_op(cmd) == SCSI_PROT_WRITE_PASS) { - cp = page_address(sg_page(sg)) + sg->offset; - ql_dbg(ql_dbg_io, vha, 0x300b, - "User data buffer=%p for cmd=%p.\n", cp, cmd); - } } /* Null termination */ *cur_dsd++ = 0; @@ -1124,8 +1101,6 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp, struct scsi_cmnd *cmd; uint32_t *cur_dsd = dsd; uint16_t used_dsds = tot_dsds; - scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); - uint8_t *cp; cmd = GET_CMD_SP(sp); scsi_for_each_prot_sg(cmd, sg, tot_dsds, i) { @@ -1169,23 +1144,11 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp, cur_dsd = (uint32_t *)next_dsd; } sle_dma = sg_dma_address(sg); - if (scsi_get_prot_op(cmd) == SCSI_PROT_WRITE_PASS) { - ql_dbg(ql_dbg_io, vha, 0x3027, - "%s(): %p, sg_entry %d - " - "addr=0x%x0x%x, len=%d.\n", - __func__, cur_dsd, i, - LSD(sle_dma), MSD(sle_dma), sg_dma_len(sg)); - } + *cur_dsd++ = cpu_to_le32(LSD(sle_dma)); *cur_dsd++ = cpu_to_le32(MSD(sle_dma)); *cur_dsd++ = cpu_to_le32(sg_dma_len(sg)); - if (scsi_get_prot_op(cmd) == SCSI_PROT_WRITE_PASS) { - cp = page_address(sg_page(sg)) + sg->offset; - ql_dbg(ql_dbg_io, vha, 0x3028, - "%s(): Protection Data buffer = %p.\n", __func__, - cp); - } avail_dsds--; } /* Null termination */ @@ -1362,6 +1325,16 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, if (!qla2x00_hba_err_chk_enabled(sp)) fw_prot_opts |= 0x10; /* Disable Guard tag checking */ + /* HBA error checking enabled */ + else if (IS_PI_UNINIT_CAPABLE(ha)) { + if ((scsi_get_prot_type(GET_CMD_SP(sp)) == SCSI_PROT_DIF_TYPE1) + || (scsi_get_prot_type(GET_CMD_SP(sp)) == + SCSI_PROT_DIF_TYPE2)) + fw_prot_opts |= BIT_10; + else if (scsi_get_prot_type(GET_CMD_SP(sp)) == + SCSI_PROT_DIF_TYPE3) + fw_prot_opts |= BIT_11; + } if (!bundling) { cur_dsd = (uint32_t *) &crc_ctx_pkt->u.nobundling.data_address; diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 06a4791c90c7..2f1adc6ac2b8 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -2150,6 +2150,19 @@ check_scsi_status: case CS_DIF_ERROR: logit = qla2x00_handle_dif_error(sp, sts24); break; + + case CS_TRANSPORT: + res = DID_ERROR << 16; + + if (!IS_PI_SPLIT_DET_CAPABLE(ha)) + break; + + if (state_flags & BIT_4) + scmd_printk(KERN_WARNING, cp, + "Unsupported device '%s' found.\n", + cp->device->vendor); + break; + default: res = DID_ERROR << 16; break; diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index e6fda177a092..b1e1dc55db24 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -109,9 +109,8 @@ MODULE_PARM_DESC(ql2xmaxqdepth, "Maximum queue depth to set for each LUN. " "Default is 32."); -/* Do not change the value of this after module load */ -int ql2xenabledif = 0; -module_param(ql2xenabledif, int, S_IRUGO|S_IWUSR); +int ql2xenabledif = 2; +module_param(ql2xenabledif, int, S_IRUGO); MODULE_PARM_DESC(ql2xenabledif, " Enable T10-CRC-DIF " " Default is 0 - No DIF Support. 1 - Enable it" @@ -1349,6 +1348,9 @@ qla2xxx_slave_configure(struct scsi_device *sdev) scsi_qla_host_t *vha = shost_priv(sdev->host); struct req_que *req = vha->req; + if (IS_T10_PI_CAPABLE(vha->hw)) + blk_queue_update_dma_alignment(sdev->request_queue, 0x7); + if (sdev->tagged_supported) scsi_activate_tcq(sdev, req->max_q_depth); else @@ -2551,7 +2553,7 @@ skip_dpc: if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) { if (ha->fw_attributes & BIT_4) { - int prot = 0; + int prot = 0, guard; base_vha->flags.difdix_supported = 1; ql_dbg(ql_dbg_init, base_vha, 0x00f1, "Registering for DIF/DIX type 1 and 3 protection.\n"); @@ -2564,7 +2566,14 @@ skip_dpc: | SHOST_DIX_TYPE1_PROTECTION | SHOST_DIX_TYPE2_PROTECTION | SHOST_DIX_TYPE3_PROTECTION); - scsi_host_set_guard(host, SHOST_DIX_GUARD_CRC); + + guard = SHOST_DIX_GUARD_CRC; + + if (IS_PI_IPGUARD_CAPABLE(ha) && + (ql2xenabledif > 1 || IS_PI_DIFB_DIX0_CAPABLE(ha))) + guard |= SHOST_DIX_GUARD_IP; + + scsi_host_set_guard(host, guard); } else base_vha->flags.difdix_supported = 0; }