aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorSagi Grimberg <sagig@mellanox.com>2014-08-13 12:54:35 -0400
committerRoland Dreier <roland@purestorage.com>2014-10-09 03:10:53 -0400
commit78eda2bb6542057b214af3bc1cae09c63e65d1d1 (patch)
treeed63e7b3396c33ee16b33cf815210fdd2a354396 /drivers/infiniband
parent3d73cf1a2a05cca7b43f7a0c16d1077065b38385 (diff)
IB/mlx5, iser, isert: Add Signature API additions
Expose more signature setting parameters. We modify the signature API to allow usage of some new execution parameters relevant to data integrity feature. This patch modifies ib_sig_domain structure by: - Deprecate DIF type in signature API (operation will be determined by the parameters alone, no DIF type awareness) - Add APPTAG check bitmask (for input domain) - Add REFTAG remap (increment) flag for each domain - Add APPTAG/REFTAG escape options for each domain The mlx5 driver is modified to follow the new parameters in HW signature setup. At the moment the callers (iser/isert) hard-code new parameters (by DIF type). In the future, callers will retrieve them from the scsi command structure. Signed-off-by: Sagi Grimberg <sagig@mellanox.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/mlx5/qp.c104
-rw-r--r--drivers/infiniband/ulp/iser/iser_memory.c50
-rw-r--r--drivers/infiniband/ulp/isert/ib_isert.c40
3 files changed, 83 insertions, 111 deletions
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index 13924a256290..d7f35e9e6522 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -2020,50 +2020,31 @@ static u8 bs_selector(int block_size)
2020 } 2020 }
2021} 2021}
2022 2022
2023static int mlx5_fill_inl_bsf(struct ib_sig_domain *domain, 2023static void mlx5_fill_inl_bsf(struct ib_sig_domain *domain,
2024 struct mlx5_bsf_inl *inl) 2024 struct mlx5_bsf_inl *inl)
2025{ 2025{
2026 /* Valid inline section and allow BSF refresh */ 2026 /* Valid inline section and allow BSF refresh */
2027 inl->vld_refresh = cpu_to_be16(MLX5_BSF_INL_VALID | 2027 inl->vld_refresh = cpu_to_be16(MLX5_BSF_INL_VALID |
2028 MLX5_BSF_REFRESH_DIF); 2028 MLX5_BSF_REFRESH_DIF);
2029 inl->dif_apptag = cpu_to_be16(domain->sig.dif.app_tag); 2029 inl->dif_apptag = cpu_to_be16(domain->sig.dif.app_tag);
2030 inl->dif_reftag = cpu_to_be32(domain->sig.dif.ref_tag); 2030 inl->dif_reftag = cpu_to_be32(domain->sig.dif.ref_tag);
2031 /* repeating block */
2032 inl->rp_inv_seed = MLX5_BSF_REPEAT_BLOCK;
2033 inl->sig_type = domain->sig.dif.bg_type == IB_T10DIF_CRC ?
2034 MLX5_DIF_CRC : MLX5_DIF_IPCS;
2031 2035
2032 switch (domain->sig.dif.type) { 2036 if (domain->sig.dif.ref_remap)
2033 case IB_T10DIF_NONE: 2037 inl->dif_inc_ref_guard_check |= MLX5_BSF_INC_REFTAG;
2034 /* No DIF */ 2038
2035 break; 2039 if (domain->sig.dif.app_escape) {
2036 case IB_T10DIF_TYPE1: /* Fall through */ 2040 if (domain->sig.dif.ref_escape)
2037 case IB_T10DIF_TYPE2: 2041 inl->dif_inc_ref_guard_check |= MLX5_BSF_APPREF_ESCAPE;
2038 inl->sig_type = domain->sig.dif.bg_type == IB_T10DIF_CRC ? 2042 else
2039 MLX5_DIF_CRC : MLX5_DIF_IPCS; 2043 inl->dif_inc_ref_guard_check |= MLX5_BSF_APPTAG_ESCAPE;
2040 /*
2041 * increment reftag and don't check if
2042 * apptag=0xffff and reftag=0xffffffff
2043 */
2044 inl->dif_inc_ref_guard_check = MLX5_BSF_INC_REFTAG |
2045 MLX5_BSF_APPREF_ESCAPE;
2046 inl->dif_app_bitmask_check = 0xffff;
2047 /* repeating block */
2048 inl->rp_inv_seed = MLX5_BSF_REPEAT_BLOCK;
2049 break;
2050 case IB_T10DIF_TYPE3:
2051 inl->sig_type = domain->sig.dif.bg_type == IB_T10DIF_CRC ?
2052 MLX5_DIF_CRC : MLX5_DIF_IPCS;
2053 /*
2054 * Don't inc reftag and don't check if
2055 * apptag=0xffff and reftag=0xffffffff
2056 */
2057 inl->dif_inc_ref_guard_check = MLX5_BSF_APPREF_ESCAPE;
2058 inl->dif_app_bitmask_check = 0xffff;
2059 /* Repeating block */
2060 inl->rp_inv_seed = MLX5_BSF_REPEAT_BLOCK;
2061 break;
2062 default:
2063 return -EINVAL;
2064 } 2044 }
2065 2045
2066 return 0; 2046 inl->dif_app_bitmask_check =
2047 cpu_to_be16(domain->sig.dif.apptag_check_mask);
2067} 2048}
2068 2049
2069static int mlx5_set_bsf(struct ib_mr *sig_mr, 2050static int mlx5_set_bsf(struct ib_mr *sig_mr,
@@ -2074,20 +2055,35 @@ static int mlx5_set_bsf(struct ib_mr *sig_mr,
2074 struct mlx5_bsf_basic *basic = &bsf->basic; 2055 struct mlx5_bsf_basic *basic = &bsf->basic;
2075 struct ib_sig_domain *mem = &sig_attrs->mem; 2056 struct ib_sig_domain *mem = &sig_attrs->mem;
2076 struct ib_sig_domain *wire = &sig_attrs->wire; 2057 struct ib_sig_domain *wire = &sig_attrs->wire;
2077 int ret;
2078 2058
2079 memset(bsf, 0, sizeof(*bsf)); 2059 memset(bsf, 0, sizeof(*bsf));
2060
2061 /* Basic + Extended + Inline */
2062 basic->bsf_size_sbs = 1 << 7;
2063 /* Input domain check byte mask */
2064 basic->check_byte_mask = sig_attrs->check_mask;
2065 basic->raw_data_size = cpu_to_be32(data_size);
2066
2067 /* Memory domain */
2080 switch (sig_attrs->mem.sig_type) { 2068 switch (sig_attrs->mem.sig_type) {
2069 case IB_SIG_TYPE_NONE:
2070 break;
2081 case IB_SIG_TYPE_T10_DIF: 2071 case IB_SIG_TYPE_T10_DIF:
2082 if (sig_attrs->wire.sig_type != IB_SIG_TYPE_T10_DIF) 2072 basic->mem.bs_selector = bs_selector(mem->sig.dif.pi_interval);
2083 return -EINVAL; 2073 basic->m_bfs_psv = cpu_to_be32(msig->psv_memory.psv_idx);
2074 mlx5_fill_inl_bsf(mem, &bsf->m_inl);
2075 break;
2076 default:
2077 return -EINVAL;
2078 }
2084 2079
2085 /* Basic + Extended + Inline */ 2080 /* Wire domain */
2086 basic->bsf_size_sbs = 1 << 7; 2081 switch (sig_attrs->wire.sig_type) {
2087 /* Input domain check byte mask */ 2082 case IB_SIG_TYPE_NONE:
2088 basic->check_byte_mask = sig_attrs->check_mask; 2083 break;
2084 case IB_SIG_TYPE_T10_DIF:
2089 if (mem->sig.dif.pi_interval == wire->sig.dif.pi_interval && 2085 if (mem->sig.dif.pi_interval == wire->sig.dif.pi_interval &&
2090 mem->sig.dif.type == wire->sig.dif.type) { 2086 mem->sig_type == wire->sig_type) {
2091 /* Same block structure */ 2087 /* Same block structure */
2092 basic->bsf_size_sbs |= 1 << 4; 2088 basic->bsf_size_sbs |= 1 << 4;
2093 if (mem->sig.dif.bg_type == wire->sig.dif.bg_type) 2089 if (mem->sig.dif.bg_type == wire->sig.dif.bg_type)
@@ -2099,20 +2095,9 @@ static int mlx5_set_bsf(struct ib_mr *sig_mr,
2099 } else 2095 } else
2100 basic->wire.bs_selector = bs_selector(wire->sig.dif.pi_interval); 2096 basic->wire.bs_selector = bs_selector(wire->sig.dif.pi_interval);
2101 2097
2102 basic->mem.bs_selector = bs_selector(mem->sig.dif.pi_interval);
2103 basic->raw_data_size = cpu_to_be32(data_size);
2104 basic->m_bfs_psv = cpu_to_be32(msig->psv_memory.psv_idx);
2105 basic->w_bfs_psv = cpu_to_be32(msig->psv_wire.psv_idx); 2098 basic->w_bfs_psv = cpu_to_be32(msig->psv_wire.psv_idx);
2106 2099 mlx5_fill_inl_bsf(wire, &bsf->w_inl);
2107 ret = mlx5_fill_inl_bsf(wire, &bsf->w_inl);
2108 if (ret)
2109 return -EINVAL;
2110
2111 ret = mlx5_fill_inl_bsf(mem, &bsf->m_inl);
2112 if (ret)
2113 return -EINVAL;
2114 break; 2100 break;
2115
2116 default: 2101 default:
2117 return -EINVAL; 2102 return -EINVAL;
2118 } 2103 }
@@ -2311,20 +2296,21 @@ static int set_psv_wr(struct ib_sig_domain *domain,
2311 memset(psv_seg, 0, sizeof(*psv_seg)); 2296 memset(psv_seg, 0, sizeof(*psv_seg));
2312 psv_seg->psv_num = cpu_to_be32(psv_idx); 2297 psv_seg->psv_num = cpu_to_be32(psv_idx);
2313 switch (domain->sig_type) { 2298 switch (domain->sig_type) {
2299 case IB_SIG_TYPE_NONE:
2300 break;
2314 case IB_SIG_TYPE_T10_DIF: 2301 case IB_SIG_TYPE_T10_DIF:
2315 psv_seg->transient_sig = cpu_to_be32(domain->sig.dif.bg << 16 | 2302 psv_seg->transient_sig = cpu_to_be32(domain->sig.dif.bg << 16 |
2316 domain->sig.dif.app_tag); 2303 domain->sig.dif.app_tag);
2317 psv_seg->ref_tag = cpu_to_be32(domain->sig.dif.ref_tag); 2304 psv_seg->ref_tag = cpu_to_be32(domain->sig.dif.ref_tag);
2318
2319 *seg += sizeof(*psv_seg);
2320 *size += sizeof(*psv_seg) / 16;
2321 break; 2305 break;
2322
2323 default: 2306 default:
2324 pr_err("Bad signature type given.\n"); 2307 pr_err("Bad signature type given.\n");
2325 return 1; 2308 return 1;
2326 } 2309 }
2327 2310
2311 *seg += sizeof(*psv_seg);
2312 *size += sizeof(*psv_seg) / 16;
2313
2328 return 0; 2314 return 0;
2329} 2315}
2330 2316
diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c
index d9ed6234c505..6c5ce357fba6 100644
--- a/drivers/infiniband/ulp/iser/iser_memory.c
+++ b/drivers/infiniband/ulp/iser/iser_memory.c
@@ -440,51 +440,44 @@ int iser_reg_rdma_mem_fmr(struct iscsi_iser_task *iser_task,
440 return 0; 440 return 0;
441} 441}
442 442
443static inline enum ib_t10_dif_type
444scsi2ib_prot_type(unsigned char prot_type)
445{
446 switch (prot_type) {
447 case SCSI_PROT_DIF_TYPE0:
448 return IB_T10DIF_NONE;
449 case SCSI_PROT_DIF_TYPE1:
450 return IB_T10DIF_TYPE1;
451 case SCSI_PROT_DIF_TYPE2:
452 return IB_T10DIF_TYPE2;
453 case SCSI_PROT_DIF_TYPE3:
454 return IB_T10DIF_TYPE3;
455 default:
456 return IB_T10DIF_NONE;
457 }
458}
459
460static inline void 443static inline void
461iser_set_dif_domain(struct scsi_cmnd *sc, struct ib_sig_attrs *sig_attrs, 444iser_set_dif_domain(struct scsi_cmnd *sc, struct ib_sig_attrs *sig_attrs,
462 struct ib_sig_domain *domain) 445 struct ib_sig_domain *domain)
463{ 446{
464 unsigned char scsi_ptype = scsi_get_prot_type(sc); 447 domain->sig_type = IB_SIG_TYPE_T10_DIF;
465
466 domain->sig.dif.type = scsi2ib_prot_type(scsi_ptype);
467 domain->sig.dif.pi_interval = sc->device->sector_size; 448 domain->sig.dif.pi_interval = sc->device->sector_size;
468 domain->sig.dif.ref_tag = scsi_get_lba(sc) & 0xffffffff; 449 domain->sig.dif.ref_tag = scsi_get_lba(sc) & 0xffffffff;
450 /*
451 * At the moment we hard code those, but in the future
452 * we will take them from sc.
453 */
454 domain->sig.dif.apptag_check_mask = 0xffff;
455 domain->sig.dif.app_escape = true;
456 domain->sig.dif.ref_escape = true;
457 if (scsi_get_prot_type(sc) == SCSI_PROT_DIF_TYPE1 ||
458 scsi_get_prot_type(sc) == SCSI_PROT_DIF_TYPE2)
459 domain->sig.dif.ref_remap = true;
469}; 460};
470 461
471static int 462static int
472iser_set_sig_attrs(struct scsi_cmnd *sc, struct ib_sig_attrs *sig_attrs) 463iser_set_sig_attrs(struct scsi_cmnd *sc, struct ib_sig_attrs *sig_attrs)
473{ 464{
474 sig_attrs->mem.sig_type = IB_SIG_TYPE_T10_DIF;
475 sig_attrs->wire.sig_type = IB_SIG_TYPE_T10_DIF;
476
477 switch (scsi_get_prot_op(sc)) { 465 switch (scsi_get_prot_op(sc)) {
478 case SCSI_PROT_WRITE_INSERT: 466 case SCSI_PROT_WRITE_INSERT:
479 case SCSI_PROT_READ_STRIP: 467 case SCSI_PROT_READ_STRIP:
480 sig_attrs->mem.sig.dif.type = IB_T10DIF_NONE; 468 sig_attrs->mem.sig_type = IB_SIG_TYPE_NONE;
481 iser_set_dif_domain(sc, sig_attrs, &sig_attrs->wire); 469 iser_set_dif_domain(sc, sig_attrs, &sig_attrs->wire);
482 sig_attrs->wire.sig.dif.bg_type = IB_T10DIF_CRC; 470 sig_attrs->wire.sig.dif.bg_type = IB_T10DIF_CRC;
483 break; 471 break;
484 case SCSI_PROT_READ_INSERT: 472 case SCSI_PROT_READ_INSERT:
485 case SCSI_PROT_WRITE_STRIP: 473 case SCSI_PROT_WRITE_STRIP:
486 sig_attrs->wire.sig.dif.type = IB_T10DIF_NONE; 474 sig_attrs->wire.sig_type = IB_SIG_TYPE_NONE;
487 iser_set_dif_domain(sc, sig_attrs, &sig_attrs->mem); 475 iser_set_dif_domain(sc, sig_attrs, &sig_attrs->mem);
476 /*
477 * At the moment we use this modparam to tell what is
478 * the memory bg_type, in the future we will take it
479 * from sc.
480 */
488 sig_attrs->mem.sig.dif.bg_type = iser_pi_guard ? IB_T10DIF_CSUM : 481 sig_attrs->mem.sig.dif.bg_type = iser_pi_guard ? IB_T10DIF_CSUM :
489 IB_T10DIF_CRC; 482 IB_T10DIF_CRC;
490 break; 483 break;
@@ -493,6 +486,11 @@ iser_set_sig_attrs(struct scsi_cmnd *sc, struct ib_sig_attrs *sig_attrs)
493 iser_set_dif_domain(sc, sig_attrs, &sig_attrs->wire); 486 iser_set_dif_domain(sc, sig_attrs, &sig_attrs->wire);
494 sig_attrs->wire.sig.dif.bg_type = IB_T10DIF_CRC; 487 sig_attrs->wire.sig.dif.bg_type = IB_T10DIF_CRC;
495 iser_set_dif_domain(sc, sig_attrs, &sig_attrs->mem); 488 iser_set_dif_domain(sc, sig_attrs, &sig_attrs->mem);
489 /*
490 * At the moment we use this modparam to tell what is
491 * the memory bg_type, in the future we will take it
492 * from sc.
493 */
496 sig_attrs->mem.sig.dif.bg_type = iser_pi_guard ? IB_T10DIF_CSUM : 494 sig_attrs->mem.sig.dif.bg_type = iser_pi_guard ? IB_T10DIF_CSUM :
497 IB_T10DIF_CRC; 495 IB_T10DIF_CRC;
498 break; 496 break;
@@ -501,10 +499,10 @@ iser_set_sig_attrs(struct scsi_cmnd *sc, struct ib_sig_attrs *sig_attrs)
501 scsi_get_prot_op(sc)); 499 scsi_get_prot_op(sc));
502 return -EINVAL; 500 return -EINVAL;
503 } 501 }
502
504 return 0; 503 return 0;
505} 504}
506 505
507
508static int 506static int
509iser_set_prot_checks(struct scsi_cmnd *sc, u8 *mask) 507iser_set_prot_checks(struct scsi_cmnd *sc, u8 *mask)
510{ 508{
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
index 73092756460b..0bea5776bcbc 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -2609,51 +2609,39 @@ isert_fast_reg_mr(struct isert_conn *isert_conn,
2609 return ret; 2609 return ret;
2610} 2610}
2611 2611
2612static inline enum ib_t10_dif_type
2613se2ib_prot_type(enum target_prot_type prot_type)
2614{
2615 switch (prot_type) {
2616 case TARGET_DIF_TYPE0_PROT:
2617 return IB_T10DIF_NONE;
2618 case TARGET_DIF_TYPE1_PROT:
2619 return IB_T10DIF_TYPE1;
2620 case TARGET_DIF_TYPE2_PROT:
2621 return IB_T10DIF_TYPE2;
2622 case TARGET_DIF_TYPE3_PROT:
2623 return IB_T10DIF_TYPE3;
2624 default:
2625 return IB_T10DIF_NONE;
2626 }
2627}
2628
2629static inline void 2612static inline void
2630isert_set_dif_domain(struct se_cmd *se_cmd, struct ib_sig_attrs *sig_attrs, 2613isert_set_dif_domain(struct se_cmd *se_cmd, struct ib_sig_attrs *sig_attrs,
2631 struct ib_sig_domain *domain) 2614 struct ib_sig_domain *domain)
2632{ 2615{
2633 enum ib_t10_dif_type ib_prot_type = se2ib_prot_type(se_cmd->prot_type); 2616 domain->sig_type = IB_SIG_TYPE_T10_DIF;
2634
2635 domain->sig.dif.type = ib_prot_type;
2636 domain->sig.dif.bg_type = IB_T10DIF_CRC; 2617 domain->sig.dif.bg_type = IB_T10DIF_CRC;
2637 domain->sig.dif.pi_interval = se_cmd->se_dev->dev_attrib.block_size; 2618 domain->sig.dif.pi_interval = se_cmd->se_dev->dev_attrib.block_size;
2638 domain->sig.dif.ref_tag = se_cmd->reftag_seed; 2619 domain->sig.dif.ref_tag = se_cmd->reftag_seed;
2620 /*
2621 * At the moment we hard code those, but if in the future
2622 * the target core would like to use it, we will take it
2623 * from se_cmd.
2624 */
2625 domain->sig.dif.apptag_check_mask = 0xffff;
2626 domain->sig.dif.app_escape = true;
2627 domain->sig.dif.ref_escape = true;
2628 if (se_cmd->prot_type == TARGET_DIF_TYPE1_PROT ||
2629 se_cmd->prot_type == TARGET_DIF_TYPE2_PROT)
2630 domain->sig.dif.ref_remap = true;
2639}; 2631};
2640 2632
2641static int 2633static int
2642isert_set_sig_attrs(struct se_cmd *se_cmd, struct ib_sig_attrs *sig_attrs) 2634isert_set_sig_attrs(struct se_cmd *se_cmd, struct ib_sig_attrs *sig_attrs)
2643{ 2635{
2644
2645 sig_attrs->mem.sig_type = IB_SIG_TYPE_T10_DIF;
2646 sig_attrs->wire.sig_type = IB_SIG_TYPE_T10_DIF;
2647
2648 switch (se_cmd->prot_op) { 2636 switch (se_cmd->prot_op) {
2649 case TARGET_PROT_DIN_INSERT: 2637 case TARGET_PROT_DIN_INSERT:
2650 case TARGET_PROT_DOUT_STRIP: 2638 case TARGET_PROT_DOUT_STRIP:
2651 sig_attrs->mem.sig.dif.type = IB_T10DIF_NONE; 2639 sig_attrs->mem.sig_type = IB_SIG_TYPE_NONE;
2652 isert_set_dif_domain(se_cmd, sig_attrs, &sig_attrs->wire); 2640 isert_set_dif_domain(se_cmd, sig_attrs, &sig_attrs->wire);
2653 break; 2641 break;
2654 case TARGET_PROT_DOUT_INSERT: 2642 case TARGET_PROT_DOUT_INSERT:
2655 case TARGET_PROT_DIN_STRIP: 2643 case TARGET_PROT_DIN_STRIP:
2656 sig_attrs->wire.sig.dif.type = IB_T10DIF_NONE; 2644 sig_attrs->wire.sig_type = IB_SIG_TYPE_NONE;
2657 isert_set_dif_domain(se_cmd, sig_attrs, &sig_attrs->mem); 2645 isert_set_dif_domain(se_cmd, sig_attrs, &sig_attrs->mem);
2658 break; 2646 break;
2659 case TARGET_PROT_DIN_PASS: 2647 case TARGET_PROT_DIN_PASS: