Re: [PATCH v5 1/2] scsi: hisi_sas: Add support for DIF feature for v2 hw

2018-12-19 Thread John Garry

On 19/12/2018 04:35, Martin K. Petersen wrote:


John,


From: Xiang Chen 

For v3 hw, we support DIF operation for SAS, but not SATA.

In addition, DIF CRC16 is supported.

This patchset adds the SW support for the described features. The main
components are as follows:
- Get protection mask from module param
- Fill PI fields
- Fill related to DIF in DQ and protection iu memories


Applied to 4.21/scsi-queue, thanks!



Thanks, and we're still looking at the DIX issue.

John



Re: [PATCH v5 1/2] scsi: hisi_sas: Add support for DIF feature for v2 hw

2018-12-18 Thread Martin K. Petersen


John,

> From: Xiang Chen 
>
> For v3 hw, we support DIF operation for SAS, but not SATA.
>
> In addition, DIF CRC16 is supported.
>
> This patchset adds the SW support for the described features. The main
> components are as follows:
> - Get protection mask from module param
> - Fill PI fields
> - Fill related to DIF in DQ and protection iu memories

Applied to 4.21/scsi-queue, thanks!

-- 
Martin K. Petersen  Oracle Linux Engineering


[PATCH v5 1/2] scsi: hisi_sas: Add support for DIF feature for v2 hw

2018-12-17 Thread John Garry
From: Xiang Chen 

For v3 hw, we support DIF operation for SAS, but not SATA.

In addition, DIF CRC16 is supported.

This patchset adds the SW support for the described features. The main
components are as follows:
- Get protection mask from module param
- Fill PI fields
- Fill related to DIF in DQ and protection iu memories

Signed-off-by: Xiang Chen 
Signed-off-by: John Garry 
---
 drivers/scsi/hisi_sas/hisi_sas.h   |   8 ++
 drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 132 -
 2 files changed, 137 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
index 912d234..af29194 100644
--- a/drivers/scsi/hisi_sas/hisi_sas.h
+++ b/drivers/scsi/hisi_sas/hisi_sas.h
@@ -69,6 +69,12 @@
 #define HISI_SAS_SATA_PROTOCOL_FPDMA   0x8
 #define HISI_SAS_SATA_PROTOCOL_ATAPI   0x10
 
+#define HISI_SAS_DIF_PROT_MASK (SHOST_DIF_TYPE1_PROTECTION | \
+   SHOST_DIF_TYPE2_PROTECTION | \
+   SHOST_DIF_TYPE3_PROTECTION)
+
+#define HISI_SAS_PROT_MASK (HISI_SAS_DIF_PROT_MASK)
+
 struct hisi_hba;
 
 enum {
@@ -268,6 +274,8 @@ struct hisi_hba {
struct pci_dev *pci_dev;
struct device *dev;
 
+   int prot_mask;
+
void __iomem *regs;
void __iomem *sgpio_regs;
struct regmap *ctrl;
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c 
b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
index 44781e3..6cd3c1a 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
@@ -127,6 +127,8 @@
 #define PHY_CTRL   (PORT_BASE + 0x14)
 #define PHY_CTRL_RESET_OFF 0
 #define PHY_CTRL_RESET_MSK (0x1 << PHY_CTRL_RESET_OFF)
+#define CMD_HDR_PIR_OFF8
+#define CMD_HDR_PIR_MSK(0x1 << CMD_HDR_PIR_OFF)
 #define SL_CFG (PORT_BASE + 0x84)
 #define AIP_LIMIT  (PORT_BASE + 0x90)
 #define SL_CONTROL (PORT_BASE + 0x94)
@@ -333,6 +335,16 @@
 #define ITCT_HDR_RTOLT_OFF 48
 #define ITCT_HDR_RTOLT_MSK (0xULL << ITCT_HDR_RTOLT_OFF)
 
+struct hisi_sas_protect_iu_v3_hw {
+   u32 dw0;
+   u32 lbrtcv;
+   u32 lbrtgv;
+   u32 dw3;
+   u32 dw4;
+   u32 dw5;
+   u32 rsv;
+};
+
 struct hisi_sas_complete_v3_hdr {
__le32 dw0;
__le32 dw1;
@@ -372,9 +384,28 @@ struct hisi_sas_err_record_v3 {
((fis.command == ATA_CMD_DEV_RESET) && \
((fis.control & ATA_SRST) != 0)))
 
+#define T10_INSRT_EN_OFF0
+#define T10_INSRT_EN_MSK(1 << T10_INSRT_EN_OFF)
+#define T10_RMV_EN_OFF 1
+#define T10_RMV_EN_MSK (1 << T10_RMV_EN_OFF)
+#define T10_RPLC_EN_OFF2
+#define T10_RPLC_EN_MSK(1 << T10_RPLC_EN_OFF)
+#define T10_CHK_EN_OFF 3
+#define T10_CHK_EN_MSK (1 << T10_CHK_EN_OFF)
+#define INCR_LBRT_OFF  5
+#define INCR_LBRT_MSK  (1 << INCR_LBRT_OFF)
+#define USR_DATA_BLOCK_SZ_OFF  20
+#define USR_DATA_BLOCK_SZ_MSK  (0x3 << USR_DATA_BLOCK_SZ_OFF)
+#define T10_CHK_MSK_OFF16
+
 static bool hisi_sas_intr_conv;
 MODULE_PARM_DESC(intr_conv, "interrupt converge enable (0-1)");
 
+/* permit overriding the host protection capabilities mask (EEDP/T10 PI) */
+static int prot_mask;
+module_param(prot_mask, int, 0);
+MODULE_PARM_DESC(prot_mask, " host protection capabilities mask, def=0x0 ");
+
 static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off)
 {
void __iomem *regs = hisi_hba->regs + off;
@@ -941,6 +972,58 @@ static void prep_prd_sge_v3_hw(struct hisi_hba *hisi_hba,
hdr->sg_len = cpu_to_le32(n_elem << CMD_HDR_DATA_SGL_LEN_OFF);
 }
 
+static u32 get_prot_chk_msk_v3_hw(struct scsi_cmnd *scsi_cmnd)
+{
+   unsigned char prot_flags = scsi_cmnd->prot_flags;
+
+   if (prot_flags & SCSI_PROT_TRANSFER_PI) {
+   if (prot_flags & SCSI_PROT_REF_CHECK)
+   return 0xc << 16;
+   return 0xfc << 16;
+   }
+   return 0;
+}
+
+static void fill_prot_v3_hw(struct scsi_cmnd *scsi_cmnd,
+   struct hisi_sas_protect_iu_v3_hw *prot)
+{
+   unsigned char prot_op = scsi_get_prot_op(scsi_cmnd);
+   unsigned int interval = scsi_prot_interval(scsi_cmnd);
+   u32 lbrt_chk_val = t10_pi_ref_tag(scsi_cmnd->request);
+
+   switch (prot_op) {
+   case SCSI_PROT_READ_STRIP:
+   prot->dw0 |= (T10_RMV_EN_MSK | T10_CHK_EN_MSK);
+   prot->lbrtcv = lbrt_chk_val;
+   prot->dw4 |= get_prot_chk_msk_v3_hw(scsi_cmnd);
+   break;
+   case SCSI_PROT_WRITE_INSERT:
+   prot->dw0 |= T10_INSRT_EN_MSK;
+   prot->lbrtgv = lbrt_chk_val;
+   break;
+   default:
+   WARN(1, "prot_op(0x%x) is not valid\n", prot_op);
+   break;
+   }
+
+   switch (interval) {
+   case 512:
+